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_buffer
。 asyncore.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()