首先我设置socket为非阻塞的。然后使用select来监控套接字。
#!/usr/bin/env python # encoding: utf-8 import socket import threading import Queue import time import select class worker(threading.Thread): def __init__(self,name,queue): self.data=queue super(worker,self).__init__(name=name) def run(self): for i in range(10000): self.data.put(i) class customer(threading.Thread): def __init__(self,name,queue): super(customer,self).__init__(name=name) self.data=queue def scan(self,ip,port): s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setblocking(False) #s.settimeout(0.1) results=s.connect_ex((ip,port)) #print results a,b,c=select.select([],[s,],[s,],0.1) #设置超时时间0.1秒,当connect连接成功的时候,代表Tcp3次握手完成,此时变成可写状态 if b: #如果socket可写,代表了端口是开放的 print port s.close() def run(self): while True: try: a=self.data.get(1,5) except: break else: ip='220.181.136.241' self.scan(ip,a) def main(): start=time.time() queue=Queue.Queue() pool=[] worke=worker('firebroo',queue) worke.start() for i in range(100): a=customer('firebroo',queue) pool.append(a) for i in pool: i.start() worke.join() for i in pool: i.join() print time.time()-start del pool[:] if __name__=='__main__': main()
大概花费17.5秒执行完毕。下面我使用settimeout。
#!/usr/bin/env python # encoding: utf-8 import socket import threading import Queue import time import select class worker(threading.Thread): def __init__(self,name,queue): self.data=queue super(worker,self).__init__(name=name) def run(self): for i in range(10000): self.data.put(i) class customer(threading.Thread): def __init__(self,name,queue): super(customer,self).__init__(name=name) self.data=queue def scan(self,ip,port): s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #s.setblocking(False) s.settimeout(0.1) #为了和前面保持一致,当然得设置0.1秒 results=s.connect_ex((ip,port)) if results==0: #connect_ex中0代表端口开放,3次握手完成 print port s.close() def run(self): while True: try: a=self.data.get(1,5) except: break else: ip='220.181.136.241' self.scan(ip,a) def main(): start=time.time() queue=Queue.Queue() pool=[] worke=worker('firebroo',queue) worke.start() for i in range(100): a=customer('firebroo',queue) pool.append(a) for i in pool: i.start() worke.join() for i in pool: i.join() print time.time()-start del pool[:] if __name__=='__main__': main()
时间大概是17.4。这两个测试结果应该可以说是一样的,难免会有误差。
情况看起来差不多,但是我更加推荐使用第一种做法。