Вам также необходимо распараллелить соединения, поскольку сокеты блокируются, когда вы устанавливаете тайм-аут. В качестве альтернативы вы могли бы не устанавливать тайм-аут и использовать модуль select.
Это можно сделать с помощью класса диспетчера в модуле 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()
Где в кластере 50 - кластере 100 есть множество машин, которые не отвечают или не существуют. Сразу начинается печать:
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.
person
JimB
schedule
30.07.2009