Python – 我怎样才能使客户端能够连接多次?

当我使用client1 = HTTPClient('192.168.1.2','3')只有它工作,但是当我使用如下:client1 = HTTPClient('192.168.1.2','3')client2 = HTTPClient('192.168.1.3 ','3')

那么整个事情变得非常缓慢,有时其中一个失败。 如何确保client1和client2连接+发送速度够快?

import asyncore, socket class HTTPClient(asyncore.dispatcher): def __init__(self, host, path): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.settimeout(10) try: self.connect( (host, 8888) ) except: print 'unable to connect' pass self.buffer = path def handle_connect(self): pass def handle_close(self): self.close() def handle_read(self): print self.recv(8192) def writable(self): return (len(self.buffer) > 0) def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] client1 = HTTPClient('192.168.1.2', '3') client2 = HTTPClient('192.168.1.3', '3') asyncore.loop() 

编辑:也尝试线程,但相同的结果

 import asyncore, socket import threading import os class HTTPClient(asyncore.dispatcher): def __init__(self, host, path): asyncore.dispatcher.__init__(self) self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.settimeout(10) try: self.connect( (host, 8888) ) except: print 'unable to connect' pass self.buffer = path def handle_connect(self): pass def handle_close(self): self.close() def handle_read(self): print self.recv(8192) def writable(self): return (len(self.buffer) > 0) def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] def t1(): client1 = HTTPClient('192.168.1.161', '3') def t2(): client2 = HTTPClient('192.168.1.163', '3') t0 = threading.Thread(target=t1()) t0.start() t0.join() t0 = threading.Thread(target=t2()) t0.start() t0.join() asyncore.loop() 

在你的代码中可能有几个问题,例如,当你指定一个目标时,放下括号: Thread(target=t1) 。 如果f是一个函数,那么f()立即调用它。 你也混合asyncore与阻止代码和多个线程。

如果你想同时建立几个http连接, 你可以使用一个线程池来代替:

 import urllib2 from multiprocessing.dummy import Pool # use threads def fetch(url): try: return url, urllib2.urlopen(url).read(), None except Exception as e: return url, None, str(e) urls = ['http://example.com', ...] pool = Pool(20) # use no more than 20 concurrent connections for url, result, error in pool.imap_unordered(fetch, urls): if error is None: print(url + " done") else: print(url + " error: " + error) 

你的HTTPClient的连接方法是阻塞的,如果你的第二个主机没有连接,你的try / except块会在超时之后激动人心。 您的except块不关闭套接字,所以acynscore.loop()仍在等待它。

尝试下面的修改,看看他们是否确认问题。 我已经把一些打印语句围绕连接方法来说明代码的阻塞部分,我已经明确地关闭了除了插座。 如果您可以发布您的服务器代码,那也是有帮助的,因为我预计问题出在那里。 如果服务器代码超出了你的控制范围,那么你的代码就会缩短到更小的时间,并且打开你的连接某种循环,但是你应该在每次迭代时退出连接尝试(等待1秒,然后是2,然后是4,然后是8,等连接尝试之间)。

 import asyncore, socket import time class HTTPClient(asyncore.dispatcher): def __init__(self, host, path): asyncore.dispatcher.__init__(self) self.HOST = host self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.settimeout(10) try: t0 = time.time() print "connecting to host:", host, '...blocking...' self.connect( (host, 80) ) print "connected to host (%s) in %0.2f seconds:"%(host, time.time()-t0) except: print 'unable to connect' self.close() self.buffer = path def handle_connect(self): pass def handle_close(self): self.close() def handle_read(self): print self.recv(8192) def writable(self): return (len(self.buffer) > 0) def handle_write(self): sent = self.send(self.buffer) self.buffer = self.buffer[sent:] client1 = HTTPClient('news.google.com', 'GET / HTTP/1.0\r\n\r\n') client2 = HTTPClient('not_a_valid_server.local', 'GET / HTTP/1.0\r\n\r\n') client3 = HTTPClient('news.yahoo.com', 'GET / HTTP/1.0\r\n\r\n') asyncore.loop()