0

私は IP = '127.0.0.1'、ポート番号 'port' を持っています。

class AClass(asyncore.dispatcher):
     def __init__(self, ip, port):        
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)        
        self.connect((ip, port))

    def handle_connect(self):
        print 'connected'   

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

    def handle_close(self):
        self.close()

しかし、何も印刷されていません。

送信は別のプロセスによって処理されています。どうすれば確認できますか? 上記は正しいですか?

編集:送信用:個別に実行される別のpythonプログラム:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((addr, port))
packet="some string"
sock.sendall(packet+'\r\n') 

何も起こりません

サーバー側に置くと(!!!)print sock.recv(4096)、パケットが印刷されているのがわかりますが、クライアント側からは何も起こりません。

4

1 に答える 1

2

AClassサーバー側になることを意味していると思います。その場合、AClassを行うべきではありませconnect()。ソケット通信には 2 つの側面があります。サーバー側では、通常、ソケットを作成し、それをアドレスとポートにバインドし、( を介してlisten()) バックログを設定し、accept()接続します。通常、クライアントから新しい接続がある場合、そのクライアントを処理するために他のエンティティを生成します。

このコードは、エコー サーバーを実装します。

import asyncore
import socket


class EchoHandler(asyncore.dispatcher_with_send):
    def handle_read(self):
        self.out_buffer = self.recv(1024)
        if not self.out_buffer:
            self.close()
        print "server:", repr(self.out_buffer)

    def handle_close(self):
        self.close()


class EchoServer(asyncore.dispatcher):
    def __init__(self, ip, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind((ip, port))
        self.listen(1)

    def handle_accept(self):
        sock, addr = self.accept()

        print "Connection from", addr

        EchoHandler(sock)

s = EchoServer('127.0.0.1', 21345)
asyncore.loop()

__init__()このメソッドでは、ソケットをバインドし、バックログを設定している ことに注意してください。handle_accept()新しい着信接続を処理するものです。この場合、 から返された新しいソケット オブジェクトとアドレスを取得し、accept()その接続用の新しい非同期ハンドラーを作成します (ソケットを に提供しますEchoHandler)。 EchoHandler次に、ソケットから読み取る作業を行い、そのデータを に入れますout_bufferasyncore.dispatcher_with_sendその後、データを送信する準備ができたことに気づき、舞台裏でソケットに書き込み、クライアントに送り返します。つまり、クライアントからデータを読み取り、向きを変えて同じデータをサーバーに送り返します。

この実装は、いくつかの方法で確認できます。接続を開き、メッセージを送信し、応答を読み取って終了する Python コードを次に示します。

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((ip, port))
client.sendall("Hello world!\r\n")
print "client:", repr(client.recv(1024))
client.close()

telnet localhost 21345この例では、コマンドを使用して telnet をクライアントとして使用することもできます。文字列を入力して Enter キーを押すと、サーバーがその文字列を送り返します。これが私が行ったセッションの例です。

:: telnet 127.0.0.1 21345
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Hello!
Hello!
aouaoeu aoeu aoeu
aouaoeu aoeu aoeu
^]
telnet> quit
Connection closed.

この例では、最初の「Hello!」はクライアントに入力したもので、2 つ目はサーバーからのエコーです。次に、別の文字列を試してみましたが、それもエコー バックされました。

これまでにソケット通信を行ったことがない場合は、Richard Stevens のUNIX ネットワーク プログラミングを十分にお勧めできません。第 3 版は現在印刷されており、Amazonで入手できます。ただし、Python や非同期コアの使用についてはカバーしていません。残念ながら、asyncore は、Python のドキュメントであまり詳しく説明されていないモジュールの 1 つです。ただし、実際にはかなりまともな例がいくつかあります。

うまくいけば、これで正しい方向に進むことができます。

EDIT : asyncore ベースのクライアントは次のとおりです。

class Client(asyncore.dispatcher_with_send):
    def __init__(self, ip, port, message):
        asyncore.dispatcher_with_send.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.connect((ip, port))
        self.out_buffer = message

    def handle_connect(self):
        print 'connected'

    def handle_read(self):
        data = self.recv(8192)
        print "client:", repr(data)

    def handle_close(self):
        self.close()
于 2012-10-10T08:34:09.977 に答える