Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 多线程端口扫描程序_Python_Multithreading_Sockets_Python 2.7 - Fatal编程技术网

Python 多线程端口扫描程序

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

是的,是的,我知道我可以使用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.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
vs
s.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
为假。您没有调用函数…您的答案应该包含对代码的解释以及如何解决问题的描述。