首先我设置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。这两个测试结果应该可以说是一样的,难免会有误差。
情况看起来差不多,但是我更加推荐使用第一种做法。