代码思想:开启线程数可以自定义,每个线程去探测一个IP地址下的设定范围内的端口,直到所有IP都被探测过。
其实对于每个IP又可以开多个线程去探测,这样会快很多,稍稍改一下就OK了。
# -*- coding: utf-8 -*-
#!/usr/bin/python
#---------------------------------------
# 程序:端口探测
# 版本:0.1
# 作者:fantasy
# 日期:2014-06-09
# 语言:Python 2.7
# 功能:输入一个IP和端口范围,探测其端口是否打开。
#----------------------------------------
from threading import Thread
from Queue import Queue
import sys
import socket
import struct
#q是任务队列
q = Queue()
#端口范围的开始和结束
port_begin=0
port_end=0
#具体的处理函数,负责处理单个IP的所有测试端口
def port_test(ip):
print 'testing %s......'%ip
for i in range(port_begin,port_end):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.1)
try:
s.connect((ip,i))
print "ip:%s port:%d"%(ip,i)
except Exception:
pass
s.close()
#工作进程,负责不断从队列取数据并处理
def working():
while True:
#python中的Queue是线程安全的,不用加锁
ip=q.get()
#整数转为点分十进制字符串
ip = socket.inet_ntoa(struct.pack('I',socket.htonl(ip)))
port_test(ip)
#向消息队列发送完成信号
q.task_done()
#输入 起始IP,结束IP,起始端口,结束端口
def main():
if len(sys.argv)!=6:
print u'输入错误,请重新输入......'
print u'输入参数:起始IP,终止IP,起始端口,结束端口,开启线程数......'
raw_input()
return
else:
#ip地址转为整数
ip_begin=socket.ntohl(struct.unpack("I",socket.inet_aton(str(sys.argv[1])))[0])
ip_end=socket.ntohl(struct.unpack("I",socket.inet_aton(str(sys.argv[2])))[0])
global port_begin
global port_end
port_begin=int(sys.argv[3])
port_end=int(sys.argv[4])
thread_num=int(sys.argv[5])
#创造有thread_num个线程的线程池
for i in range(thread_num):
t = Thread(target=working)
t.setDaemon(True)
t.start()
#把所有ip放入队列
for i in range(ip_begin,ip_end+1):
q.put(i)
#等待所有IP探测完成
q.join()
main()