Python 线程池扫描端口
昨天纠结了一会儿线程池的问题,终于可以使这个线程池可用了,真切的感受到了多线程的执行速度确实很犀利,原来的单线程端口扫描那个速度实在不敢恭维,换
成多线程之后马上有了数量级的飞跃(当然看你定义线程数的大小,不能太大,否则线程的额外开销会严重影响性能,过犹不及),下面是代码部分:
from socket import *
from threading import Thread
from Queue import Queue
def scan(ip,port):
s=socket(AF_INET,SOCK_STREAM)
result=s.connect_ex((ip,port))
if(result==0):
print 'Port %d: OPEN' % port
s.close()
class Worker(Thread):
def __init__(self,taskQueue):
Thread.__init__(self)
self.setDaemon(True)
self.taskQueue=taskQueue
self.start()
def run(self):
while True:
try:
callable,args,kwds=self.taskQueue.get()
callable(*args,**kwds)
except:
break
class ThreadPool:
def __init__(self,ip):
self.threads=[]
self.taskQueue=Queue()
self.threadNum=10
self.__create_taskqueue(ip)
self.__create_threadpool(self.threadNum)
def __create_taskqueue(self,ip):
for i in range(20,10000):
self.add_task(scan,ip,i)
def __create_threadpool(self,threadNum):
for i in range(threadNum):
thread=Worker(self.taskQueue)
self.threads.append(thread)
def add_task(self,callable,*args,**kwds):
self.taskQueue.put((callable,args,kwds))
def waitfor_complete(self):
while len(self.threads):
thread=self.threads.pop()
thread.join(0.1)
if thread.isAlive() and not self.taskQueue.empty():
self.threads.append(thread)
print 'scaning is over!'
if __name__=='__main__':
target=raw_input('Enter host to scan:')
targetIP=gethostbyname(target)
print 'Starting scan on host',targetIP
tp=ThreadPool(targetIP)
tp.waitfor_complete()
在这里就直说小callable这个函数,它的功能是检查一个对象(python里面皆是对象)是否是可调用的,如果为真则返回True,如果为假则返回False。对于一个类来说,如果其含有__call__()方法,则也被认为是可调用的。
来源:http://www.oschina.net/question/220339_76762