当我使用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()
答案 0 :(得分:2)
你的HTTPClient的连接方法是阻塞的,如果你的第二个主机没有连接,你的try / except块在超时后就会激动。你的except块没有关闭套接字,所以acynscore.loop()仍在等待它。
尝试下面的修改,看看他们是否确认了问题。我已经在connect方法周围添加了一些打印语句来说明代码的阻塞部分,并且我已经明确地关闭了except中的套接字。如果您可以发布您的服务器代码也会有所帮助,因为我预计问题就在那里。如果服务器代码不在您的控制范围内,您可以将代码缩短到更小的时间并打开连接某种循环,但是您应该在每次迭代时退出连接尝试(等待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()
答案 1 :(得分:1)
您的代码中可能存在多个问题,例如,在指定目标时删除括号: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)