Python 多线程端口扫描程序
是的,是的,我知道我可以使用nmap,但我想自己试试 我正在尝试编写一个线程脚本来查找目标IP地址上打开的端口。这就是我现在拥有的:Python 多线程端口扫描程序,python,multithreading,sockets,python-2.7,Python,Multithreading,Sockets,Python 2.7,是的,是的,我知道我可以使用nmap,但我想自己试试 我正在尝试编写一个线程脚本来查找目标IP地址上打开的端口。这就是我现在拥有的: import socket, Queue from threading import Thread print "Target to scan: " targetIP = raw_input("> ") print "Number of threads: " threads = int(raw_input("> ")) q = Queue.Qu
import socket, Queue
from threading import Thread
print "Target to scan: "
targetIP = raw_input("> ")
print "Number of threads: "
threads = int(raw_input("> "))
q = Queue.Queue()
# Fill queue with port numbers
for port in range(1, 1025):
q.put(port)
def scan(targetIP, port):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(4)
result = s.connect_ex((targetIP, port))
if result == 0:
print 'Port {0} is open'.format(port)
s.close
q.task_done()
while q.full:
for i in range(threads):
port = q.get()
t = Thread(target=scan, args =(targetIP, port))
t.daemon = True
t.start()
但是,我有几个问题:
1) 当我按原样运行它时,它将遍历端口队列,但只是挂起,即使队列清空,也不会中断while
循环
2) 如果我在scan
中添加一个打印行以查看发生了什么,基本上在开始处添加一个“扫描端口X”行,在结束处添加一个print result
行,stdout会被队列中所有端口的“扫描端口”行淹没,然后打印结果行。这意味着,当前脚本似乎没有等待result
获取值,而是继续迭代,就好像它已经得到了值一样
我在这里做错了什么?您必须知道,仅通过迭代线程数范围内的数字并执行线程,并不能保持所需的线程数。它只循环4次,创建4个线程,再次循环,然后进入另一个相同的循环并创建另一个4,而不确定这4个线程是否已完成任务,因此当您在扫描函数中输入prints时,会收到大量消息 您必须等待孩子们在while body部分结束时完成 我认为:
threading.wait()
你有几个问题,第一个是:
while q.full:
您可能打算调用该函数:
while q.full():
但是您有一个无限队列(您创建它时没有maxsize),所以它永远不会满;因此,如果您进行了更改,它根本不会调用scan()
假设您以其他方式解决了这个问题(例如,使用q.empty()
),如果range(threads)
不能均匀地划分队列中的项目,会发生什么情况?例如,假设您使用3个线程,并将端口号1、2、3和4放入q
。您将在第一次调用q.get()
三次(获取1、2和3),然后在第二次调用中再次调用它三次,但其中只有一个值,4
,因此之后对q.get()
的调用将等待某人执行q.put()
,你会被卡住的
换句话说,你需要重写逻辑
编辑:与
s.close
vss.close()
相同的问题。其他人则从这一方面讨论了整个线程池@Blender的版本使用了多处理
,它简单得多,因为多处理
为您解决了这一问题。您的代码存在一些问题。首先,while循环一直持续到函数q.full失效。但实际上没有必要在主线程中循环
我会将sentinel值添加到队列的末尾,每个工作线程一个。当工作线程获得sentinel时,它退出其处理循环。这样就不必对线程进行后台监控
因此,您的代码应该如下所示:
- 将端口放入队列
- 让哨兵排队
- 启动所需数量的线程,让它们从队列中获取端口并进行处理,将结果放入另一个队列
- 等待线程终止,在辅助线程上调用
t.join()
- 使用结果
多处理.Pool
而不是线程化
:
import socket
from multiprocessing import Pool
def scan(arg):
target_ip, port = arg
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
try:
sock.connect((target_ip, port))
sock.close()
return port, True
except (socket.timeout, socket.error):
return port, False
if __name__ == '__main__':
target_ip = raw_input('Target IP: ')
num_procs = int(raw_input('Number of processes: '))
ports = range(1, 1025)
pool = Pool(processes=num_procs)
for port, status in pool.imap_unordered(scan, [(target_ip, port) for port in ports]):
print port, 'is', 'open' if status else 'closed'
试试这个:
import socket
import threading
from queue import Queue
print_lock = threading.Lock()
target = 'pythonprogramming.net'
def portscan(port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
con = s.connect((target,port))
with print_lock:
print('port',port,'is open!')
con.close()
except:
pass
def threader():
while True:
worker = q.get()
portscan(worker)
q.task_done()
q = Queue()
for x in range(30):
t = threading.Thread(target=threader)
t.daemon = True
t.start()
for worker in range(1,10000):
q.put(worker)
q.join()
意思是,当前脚本似乎没有等待结果获取值,而是继续迭代,就好像它已经获得值一样。
意思是,脚本在多个线程中运行,而不是按顺序运行?这不是你一开始想要的吗?等待是直到q.full
为假。您没有调用函数…您的答案应该包含对代码的解释以及如何解决问题的描述。