タイムアウトを設定するとソケットがブロックされるため、接続も並列化する必要があります。または、タイムアウトを設定できず、選択モジュールを使用できませんでした。
これは、 asyncoreモジュールのディスパッチャー クラスで実行できます。基本的なhttp クライアントの例を見てください。そのクラスの複数のインスタンスは、接続時に互いにブロックしません。これは、スレッドを使用して簡単に行うことができます。また、ソケット タイムアウトの追跡が容易になると思いますが、既に非同期メソッドを使用しているため、同じ道を歩むこともできます。
例として、以下は私のすべての Linux システムで動作します
import asyncore, socket
class client(asyncore.dispatcher):
def __init__(self, host):
self.host = host
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, 22))
def handle_connect(self):
print 'Connected to', self.host
def handle_close(self):
self.close()
def handle_write(self):
self.send('')
def handle_read(self):
print ' ', self.recv(1024)
clients = []
for i in range(50, 100):
clients.append(client('cluster%d' % i))
asyncore.loop()
cluster50 ~ cluster100 には、応答しない、または存在しないマシンが多数あります。これにより、すぐに印刷が開始されます。
Connected to cluster50
SSH-2.0-OpenSSH_4.3
Connected to cluster51
SSH-2.0-OpenSSH_4.3
Connected to cluster52
SSH-2.0-OpenSSH_4.3
Connected to cluster60
SSH-2.0-OpenSSH_4.3
Connected to cluster61
SSH-2.0-OpenSSH_4.3
...
ただし、これは、ブロックする必要がある getaddrinfo を考慮していません。DNS クエリの解決に問題がある場合は、すべてを待つ必要があります。おそらく、DNS クエリを自分で個別に収集し、非同期ループで IP アドレスを使用する必要があります。
asyncore よりも大きなツールキットが必要な場合は、Twisted Matrixをご覧ください。始めるのは少し大変ですが、Python 用に入手できる最高のネットワーク プログラミング ツールキットです。