Python端口扫描器异常重复输出:实现单次错误提示并终止程序
解决多线程端口扫描器
socket.gaierror重复输出并终止程序的问题 要实现仅输出一次错误信息并立即终止所有扫描线程,你可以通过线程安全的状态标记+提前关闭线程池的方式处理:
修改后的代码示例
import socket from concurrent.futures import ThreadPoolExecutor import threading # 线程安全的标志:标记是否已捕获gaierror异常 error_occurred = threading.Event() def scan_port(host, port): # 如果已经发生错误,直接返回,不再执行扫描 if error_occurred.is_set(): return try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.settimeout(0.5) result = s.connect_ex((host, port)) if result == 0: print(f"Port {port} is open") except socket.gaierror: # 仅当第一次触发时输出错误并终止程序 if not error_occurred.is_set(): error_occurred.set() print("错误:无法解析主机地址,请检查目标主机是否正确") # 关闭线程池,取消所有待执行任务 executor.shutdown(wait=False, cancel_futures=True) if __name__ == "__main__": target_host = "example.invalid" # 用于测试gaierror的无效主机 executor = ThreadPoolExecutor(max_workers=10) try: for port in range(1, 1026): if not error_occurred.is_set(): executor.submit(scan_port, target_host, port) executor.shutdown(wait=True) except: pass
关键实现细节:
- 线程安全标志:用
threading.Event()创建error_occurred,确保多线程环境下只有第一个捕获到gaierror的线程会输出错误信息,后续线程检测到标志已设置会直接返回。 - 立即终止线程池:捕获异常后调用
executor.shutdown(wait=False, cancel_futures=True),cancel_futures=True会取消所有尚未开始执行的任务,wait=False让主线程不等待已运行的线程结束(已运行的线程会通过检查error_occurred标志提前退出)。 - 前置检查:在提交任务和扫描函数开头都检查
error_occurred状态,尽可能减少不必要的任务提交和执行。
这样就能保证socket.gaierror异常只会被输出一次,并且程序会快速终止所有扫描任务。
内容的提问来源于stack exchange,提问作者gummy otter
相关产品推荐
相关产品推荐

