Python端口扫描程序运行过慢、无法将输出写入文本文件问题排查
端口扫描程序问题修复方案
扫描速度极慢问题
这个现象完全不正常,正常1-1024端口TCP扫描对常规目标耗时不会超过数分钟,跑1小时未完成的核心诱因有两个:
- 采用单线程串行扫描逻辑:所有端口的连接请求按顺序逐个发起,前一个端口返回结果前不会处理下一个端口
- 未给socket设置连接超时:
connect_ex()默认使用系统级TCP超时配置(通常为20-75秒),遇到被防火墙丢包、无响应的端口时,会等待满超时时间才返回结果,累计等待时间极长
修复方式
- 给每个socket设置1秒的短连接超时,快速跳过无响应端口
- 用线程池实现并发扫描,同时发起多个端口的连接检测,大幅缩短总耗时
注意:并发线程数不要开太高,建议控制在50-200之间,避免触发目标防火墙拦截或者本地系统端口耗尽
输出无法保存到文本文件问题
现有注释中的写文件逻辑有两个致命问题:
- 写文件代码放在
try-except块外部,扫描过程中只要触发任意异常(Ctrl+C中断、主机不可达、域名解析失败),程序会直接执行sys.exit()退出,根本不会走到写文件的代码段 - 仅写入了循环最后一次的
port变量值,没有收集扫描过程中输出的开放端口、扫描耗时等实际结果
修复方式
两种方案可选:
- 代码内收集所有扫描结果,扫描结束(包括异常退出场景)统一写入文件
- 无需修改代码,运行脚本时直接用系统重定向命令保存输出:
- 仅保存到文件:
python3 scan.py > Hostreport.txt - 同时在屏幕显示+保存到文件:
python3 scan.py | tee Hostreport.txt
- 仅保存到文件:
修复后完整可运行代码
#!/usr/bin/env python import socket import subprocess import sys from datetime import datetime from concurrent.futures import ThreadPoolExecutor, as_completed # 单端口扫描逻辑 def scan_port(ip, port): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) # 设置1秒连接超时 result = sock.connect_ex((ip, port)) sock.close() return port if result == 0 else None if __name__ == "__main__": subprocess.call('clear', shell=True) output = [] # 统一收集所有输出内容,用于写文件 remoteServer = input("Enter a remote host to scan: ") t1 = datetime.now() open_ports = [] try: remoteServerIP = socket.gethostbyname(remoteServer) banner = "-"*60 + f"\nPlease wait, scanning remote host {remoteServerIP}\n" + "-"*60 print(banner) output.append(banner) # 100线程并发扫描 with ThreadPoolExecutor(max_workers=100) as executor: futures = [executor.submit(scan_port, remoteServerIP, port) for port in range(1,1025)] for future in as_completed(futures): res = future.result() if res: port_info = f"Port {res}: Open" print(port_info) open_ports.append(port_info) except KeyboardInterrupt: msg = "You pressed Ctrl+C" print(msg) output.append(msg) sys.exit() except socket.gaierror: msg = "Hostname could not be resolved. Exiting" print(msg) output.append(msg) sys.exit() except socket.error: msg = "Host is not available" print(msg) output.append(msg) sys.exit() finally: # 无论正常/异常退出,都计算耗时、写入文件 t2 = datetime.now() total = t2 - t1 time_msg = f'Scanning Completed in: {total}' print(time_msg) output.extend(open_ports) output.append(time_msg) with open('Hostreport.txt', 'a', encoding='utf-8') as f: f.write('\n'.join(output) + '\n')
内容的提问来源于stack exchange,提问作者Uday
相关产品推荐
相关产品推荐

