Python多线程端口扫描器

3

我正在编辑一个使用线程的端口扫描器,但是遇到了问题。

以下是原始代码的基本内容:

for i in range(0, 2000):  

    s = socket(AF_INET, SOCK_STREAM)  
    result = s.connect_ex((TargetIP, i))  

    if(result == 0) :  
        c = "Port %d: OPEN\n" % (i,)  

    s.close()

需要大约33分钟才能完成。因此,我想将它作为线程运行,以使其运行速度更快。这是我第一个线程项目,所以并不太极端,但我已经运行了下面的代码一个小时了,既没有异常也没有输出。我是线程做错了还是怎么样?

import threading
from socket import *
import time

a = 0
b = 0
c = ""
d = ""

def ScanLow():
    global a
    global c

    for i in range(0, 1000):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            c = "Port %d: OPEN\n" % (i,)  

        s.close()  
        a += 1

def ScanHigh():
    global b
    global d

    for i in range(1001, 2000):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            d = "Port %d: OPEN\n" % (i,)  

        s.close()  
        b += 1

Target = raw_input("Enter Host To Scan:")
TargetIP = gethostbyname(Target)

print "Start Scan On Host ", TargetIP
Start = time.time()

threading.Thread(target = ScanLow).start()
threading.Thread(target = ScanHigh).start()

e = a + b

while e < 2000:
    f = raw_input()

End = time.time() - Start
print c
print d
print End

g = raw_input()

这不是你的主要问题(请参见下面的答案),但请注意,您的修订与原始版本不同,未检查端口1000 - martineau
2个回答

5

这就是您的代码失败的地方。

threading.Thread(target = ScanLow).start()
threading.Thread(target = ScanHigh).start()

e = a + b

while e < 2000:
   f = raw_input()

在启动线程后,立即将值设置为e。但是之后你从未更新e的值,因此循环永远不会退出。

同时,似乎你正在等待两个线程都完成。使用join()方法是更好的方式。

from threading import Thread
threads = []
threads.append(Thread(target = ScanLow))
threads.append(Thread(target = ScanHigh))
for thread in threads:
  thread.start()
//both threads are running
for thread in threads:
  thread.join()
//both threads have stopped

编辑: 与您的问题无关,但这是一个有用的评论。您的两个扫描函数正在执行完全相同的操作。您可以用一个带有扫描范围参数的函数替换它们,并使用一个函数启动两个线程。

from threading import Thread
def Scan(start, stop):
    global a
    global c

    for i in range(start, stop):  
        s = socket(AF_INET, SOCK_STREAM)  
        result = s.connect_ex((TargetIP, i))  

        if(result == 0) :  
            c = "Port %d: OPEN\n" % (i,)  

        s.close()  
        a += 1

threadCount = 2
totalPorts = 2000
threads = []
for start in xrange(0, totalPorts, totalPorts/threadCount):
    threads.append(Thread(target = Scan, args = (start, totalPorts/threadCount)))

for thread in threads:
  thread.start()
//both threads are running
for thread in threads:
  thread.join()
//both threads have stopped

现在,您可以轻松调整扫描的线程数和端口号。


线程.追加(线程(目标=扫描, 参数=(开始,总端口/线程数)))名称错误: 名称"线程"未定义我没有想到要提到这一点,但也许我们不是使用同一个Python版本。我使用的是2.6版本。 - Amnite
抱歉,我是个新手。我将“Import threading”更改为“from threading import *”,这样就可以了。非常感谢您的帮助。它运行得很好,我学到了更多关于线程的知识(尽管我仍在研究您代码的一些具体细节)。非常感谢! - Amnite

1

您使用了一种笨拙的线程监视方法。使用 join 可以指示线程何时完成。此外,没有理由不启动更多线程以加快结果速度:

import threading
import socket
import time

ports = []
def check_port(ip,port):
    s = socket.socket()
    if s.connect_ex((ip,port)) == 0:
        ports.append(port)
    s.close()

target = raw_input('Target? ')
s = time.time()
threads = []
for port in range(2000):
    t = threading.Thread(target=check_port,args=(target,port))
    t.start()
    threads.append(t)
for t in threads:
    t.join()
print ports
print time.time() - s

输出

[80, 135, 445, 1028]
6.92199993134

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接