質問

AF_UNIXソケットを使用したASYNCOREを使用していくつかの問題があります。このコード

import asyncore, socket, os
class testselect(asyncore.dispatcher):

    path = '/tmp/mysocket'

    def __init__(self):

        asyncore.dispatcher.__init__(self)

        self.create_socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        self.bind(self.path)
        self.buffer = 'buffer'

    def handle_connect(self):

        print 'handle_connect'
        pass

    def handle_close(self):
        print 'handle_close'
        if os.path.exists(self.path)       
             os.remove(self.path)
        self.close()

    def handle_read(self):
        print 'handle_read'
        print self.recv(8192)

    def writable(self):
        print 'writable'
        return (len(self.buffer) > 0)

    def handle_write(self):
        print 'handle_write'
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]


    client = testselect()
    asyncore.loop()
.

コードを実行した場合

 $ python select_prova.py
 writable
 handle_connect
 handle_write
 handle_close
 $  
.

すぐに終了し、読み書きを待ちません。常にFalseを返すようにコードを変更するようにコードを変更した場合、入力のために正しく待機して、こののようにSocatと通信できます。

 $ socat readline UNIX:/tmp/mysocket
.

読み取り専用の場合(Writable()はFalseを返すため、論理的には機能しません)。私のコードにエラーがあるか、ASYNCORE / SELECT()でAF_UNIXソケットを管理できませんか?

役に立ちましたか?

解決

他の回答が指しているので、受信側を指定する必要があるデータグラムを送信するとき。それが立っているので、あなたのtestselectクラスはサーバーよりもクライアントのように見えます。

これらのいくつかを確認します。 asyncore examplesの例は、希望するものに近い - TimeChannelsocket.AF_INETに変更し、バインドアドレスのソケットパスを使用してUNIXドメインソケットを使用します。


通常、UDP INETソケットの作成を示す一般的なsocket.AF_UNIXを設定します。 UNIXドメインソケットはIPCの形式です。 socket.SOCK_DGRAMに変更し、socket.SOCK_STREAMを呼び出して、self.listen([backlog])などを実装する必要があります。

af_unixでsock_dgramを使用した場合、サーバが終了するのは、handle_accept()を起動するとwritableを表示しているため、handle_writeが実行され、'buffer'をただちに含むパケットを送信します。

返信前にパケットを受信するまでサーバーが待機したい場合は、handle_connectまたはhandle_readにバッファを設定してください。

    def __init__(self):
        ...
        self.buffer = ''

    def handle_connect(self):
        self.buffer = 'buffer'
.

サーバーを起動すると、socatからパケットを受信するまで待機します。


あなたの例を改装するためにあなたの例を書き直しました:

import asyncore, socket, os

class testselect(asyncore.dispatcher):

    path = '/tmp/mysocket'

    def __init__(self):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(self.path)
        self.listen(5)

    def handle_accept(self):
        client = self.accept()
        if client is None:
            pass
        else:
            handler = testhandler(*client)

class testhandler(asyncore.dispatcher_with_send):

    def __init__(self, sock, addr):
        asyncore.dispatcher_with_send.__init__(self, sock)
        self.addr = addr
        self.buffer = 'greetings'

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        self.send(self.buffer)
        self.buffer = ''

    def handle_close(self):
        self.close()

server = testselect()
try:
    asyncore.loop()
finally:
    if os.path.exists(testselect.path):
        os.unlink(testselect.path)
.

他のヒント

あなたの難易度はSock_Dgramを使っているという事実に煮ることができます。私が知ることができるものから、基本的にasyncore(No recvfromまたはsendto)でSOCK_DGRAMソケットを効果的に処理できません。さらに、SocatはSOCK_DGRAM UNIXドメインソケットを操作する方法を持っていないようです。

SOCK_DGRAMソケットには、接続の実際の概念がないため、常に選択通話で書き込み可能に登録します。しかし、実際にwriteを実行すると、宛先アドレスを指定していないため失敗します。

他の答えは用語が間違っていますが、基本的には正しいです。あなたはここでsock_streamソケットを使う必要があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top