Вам также необходимо распараллелить соединения, так как сокеты блокируются, когда вы устанавливаете время ожидания. Кроме того, вы не можете установить время ожидания и использовать модуль выбора.
Это можно сделать с помощью класса диспетчера в модуле 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.