端口扫描器优化:将端口-服务映射移出循环提升速度
端口扫描器优化方案
核心问题分析
你的扫描器运行缓慢,除了循环内大量if/elif的线性判断拖慢效率外,还存在一个隐藏问题:循环外创建的单个Socket未在每次连接后关闭,会导致连接状态异常;同时if/elif的逐个匹配效率远不如字典的哈希查找。
具体优化步骤
- 用字典存储端口-服务映射:把端口与对应服务的映射关系提前定义在循环外,查找时直接通过字典键值对获取,时间复杂度从O(n)降到O(1),彻底将映射逻辑移出扫描循环。
- 每次扫描后关闭Socket:单个Socket重复使用会引发连接状态问题,建议每次循环内创建新的Socket实例,扫描完成后立即关闭。
- 统一输出逻辑:通过字典的
get方法处理服务名称,未知端口直接显示「未知服务」,避免冗余的条件判断。
优化后的完整代码
import socket import pyfiglet from colorama import Fore # 提前定义端口-服务映射字典,放置在循环外 PORT_SERVICE_MAP = { 80: 'http', 21: 'ftp', 22: 'ssh', 23: 'telnet', 554: 'RTSP', 5432: 'PostgreSQL', 3306: 'MySQL' } ascii_banner = pyfiglet.figlet_format("Port Scanner") print(ascii_banner) remoteserver = input('请输入目标地址:') remoteserverIP = socket.gethostbyname(remoteserver) # 域名解析 for port in range(1, 22): # 每次循环创建新Socket,避免连接状态异常 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置超时时间,进一步提升扫描效率(可选但推荐) sock.settimeout(0.5) result = sock.connect_ex((remoteserverIP, port)) if result == 0: print(f"{port} 端口开放") # 从字典获取服务名,不存在则显示「未知服务」 service = PORT_SERVICE_MAP.get(port, '未知服务') print(f" 服务: {service}") sock.close() # 关闭当前Socket
额外提速建议
如果想要进一步提升扫描速度,可使用多线程/多进程同时扫描多个端口,避免单线程等待连接超时的时间浪费,比如用concurrent.futures.ThreadPoolExecutor实现并发扫描。
内容的提问来源于stack exchange,提问作者John Adams
相关产品推荐
相关产品推荐

