关于python如何实现多线程,可以参考:https://www.cnblogs.com/fnng/p/3670789.html

具体实现

1.利用TCP连接扫描一个给定的(host,port)

        TCP_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        TCP_socket.settimeout(1)
        TCP_socket.connect((host,port))

新建一个TCP socket,并尝试对给定的(host,port)进行TCP连接。为了防止在一个连接上等待太久,将socket的连接超时时间设置为1s。

因为这是一个I/O操作,为了处理可能出现的异常,用try...except模块来进行异常处理。我们希望在连接成功时能够输出该次连接开放的端口,并将开放的端口总数+1,在连接失败时不采取任何操作。

    global OpenPortNum
    try:
        TCP_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        TCP_socket.settimeout(1)
        TCP_socket.connect((host,port))
        lock.acquire()
        OpenPortNum+=1
        print('port %d : open'%port)
        lock.release()
        TCP_socket.close()
    except:
        pass

因为每个线程不能同时修改OpenPortNum,所以先使用lock.acquire()获得一个锁,只有有锁的线程能够修改OpenPortNum,操作完后再使用lock.release()释放锁,其他的线程才能继续修改OpenPortNum。

2.多线程扫描

    for p in range(1,65535):
        t = threading.Thread(target=scan,args=('192.168.109.1',p))
        threads.append(t)
        t.start()
        
    for t in threads:
        t.join

扫描过程如下

1、取出一个端口

2、新建一条线程

3、利用scan函数对该(host,port)进行扫描

4、调用thread.start()方法使扫描的子线程开始工作

5、调用thread.join()方法使主线程阻塞,等子线程死亡后再执行。

完整代码如下

import socket
import threading

lock = threading.Lock()
threads = []
OpenPortNum = 0

def scan(host,port):
    global OpenPortNum
    try:
        TCP_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        TCP_socket.settimeout(1)
        TCP_socket.connect((host,port))
        lock.acquire()
        OpenPortNum+=1
        print('port %d : open'%port)
        lock.release()
        TCP_socket.close()
    except:
        pass

def main():
    for p in range(1,65535):
        t = threading.Thread(target=scan,args=('192.168.109.1',p))
        threads.append(t)
        t.start()
        
    for t in threads:
        t.join
        
    print('A total of %d port are opend'%(OpenPortNum))

if __name__ == '__main__':
    main()

参考链接:
https://zhuanlan.zhihu.com/p/26419543

https://blog.51cto.com/jackor/2093385