我正在用Python编写端口扫描程序,基本代码如下:
import socket
import sys
import threading
def scan_port(host, port, timeout):
addr = str(host), int(port)
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conn.settimeout(float(timeout))
try:
conn.connect(addr)
print(f'- {port} open')
except Exception as error:
print(f'- {port} closed: {error!r}')
finally:
conn.close()
if __name__ == '__main__':
host = sys.argv[1]
pmin = int(sys.argv[2])
pmax = int(sys.argv[3])
threads = []
for port in range(pmin, pmax+1):
args = [host, port, 1.0]
thread = threading.Thread(target=scan_port, args=args)
thread.start()
threads.append(thread)
for thread in threads:
thread.join()
当我在单个端口上运行此脚本时,它始终会连接:
$ python scantest.py google.com 80 80
- 80 open
但是,当我在大量端口(至少100个)上运行它时,它总是会失败(出现通用的“超时”错误):
$ python scantest.py google.com 1 100
- 1 closed: timeout('timed out')
- 2 closed: timeout('timed out')
- 3 closed: timeout('timed out')
- 4 closed: timeout('timed out')
# etc...
是否存在一些使我无法对大量套接字连接进行多线程处理的Python怪癖,还是我缺少一些基本的障碍?我可以在Windows 8上运行此程序,如果有帮助的话。谢谢。
编辑:从进一步的研究来看,似乎系统一次可以尝试进行多少个套接字连接是一个限制。我已经使用ThreadPoolExecutor
模块中的concurrent.futures
重新实现了此脚本,它显着提高了可靠性(以速度为代价)。