Python端口扫描器单端口扫描正常,批量扫描结果异常求助
Python端口扫描器批量扫描异常问题分析与解决
问题描述
开发的Python端口扫描器在单端口扫描时结果准确,但批量扫描所有端口时,结果与单端口扫描不一致,且每次批量扫描的开放端口随机变化(仅扫描路由器时53端口始终显示开放)。
单端口扫描代码及结果
#! /usr/bin/python import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "192.168.1.8" port = 443 def portscanner(): if sock.connect_ex((host,port)): print ("Port %d is closed" % (port)) else: print("Port %d is open" % (port)) portscanner()
运行结果:
Port 443 is open.
批量扫描代码及异常结果
#! /usr/bin/python import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = "192.168.1.1" def portscanner(): closed = 0 opened = 0 for port in range (0, 65535): if sock.connect_ex((host,port)): closed += 1 else: print("Port %d is open" % (port)) opened += 1 print_port(closed, opened) def print_port(closed, opened): print ("%d ports are opened" % (opened)) print ("%d ports are closed" % (closed)) portscanner()
第一次运行结果:
Port 34452 is open
1 ports are opened
65534 ports are closed
再次运行结果:
Port 52016 is open
1 ports are opened
65534 ports are closed
扫描路由器时结果:
Port 53 is open
1 ports are opened
65534 ports are closed
问题根源
核心错误是复用了同一个TCP Socket对象。TCP是面向连接的协议,Socket对象在完成一次connect_ex调用后,内部状态会发生改变(无论连接成功或失败),无法再用于后续的连接操作。后续循环中复用该Socket调用connect_ex时,返回的结果是未定义的随机错误码,导致端口状态误判。
路由器53端口(DNS服务)每次都显示开放,是因为第一次扫描到该端口时Socket状态正常,连接成功;后续的端口扫描因Socket状态异常返回错误结果,但不影响已输出的53端口结果。
修复方案
每次扫描端口时创建新的Socket对象,确保每次连接都处于初始状态,同时添加超时设置提升扫描效率:
#! /usr/bin/python import socket host = "192.168.1.1" def portscanner(): closed = 0 opened = 0 # 扫描1-65535端口(0为保留端口,无需扫描) for port in range(1, 65536): # 每次循环创建新的Socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 设置超时时间,避免等待过长 sock.settimeout(0.1) # 尝试连接端口 result = sock.connect_ex((host, port)) if result == 0: print(f"Port {port} is open") opened += 1 else: closed += 1 # 关闭Socket释放资源 sock.close() print_port(closed, opened) def print_port(closed, opened): print(f"{opened} ports are opened") print(f"{closed} ports are closed") portscanner()
修改说明
- 每次循环内新建Socket,保证连接状态初始化为新
- 添加
settimeout设置,避免扫描未开放端口时阻塞过久 - 扫描完成后关闭Socket,释放系统资源
- 调整端口范围为1-65535,跳过无实际意义的保留端口0
内容的提问来源于stack exchange,提问作者Kko_Viv
相关产品推荐
相关产品推荐

