为何Python Socket扫描本地端口速度远超预期?(Ubuntu环境)
本地端口扫描速度远超外部主机的原因(Ubuntu环境)
示例代码(出自《CPython Internals》)
from queue import Queue import socket import time timeout = 1.0 def check_port(host: str, port: int, results: Queue): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) result = sock.connect_ex((host, port)) if result == 0: results.put(port) sock.close() if __name__ == '__main__': start = time.time() host = "localhost" results = Queue() for port in range(80, 100): check_port(host, port, results) while not results.empty(): print("Port {0} is open".format(results.get())) print("Completed scan in {0} seconds".format(time.time() - start))
问题描述
当脚本中host设为localhost时,扫描1至65535端口仅需约1.5秒,且设置的timeout=1.0完全不起作用;但扫描外部主机(如8.8.8.8)时,扫描440-444端口耗时约4秒,符合超时时间的预期。请问在Ubuntu环境下,为何本地端口扫描速度如此之快?
原因解析
本地TCP连接的内核处理逻辑:
localhost对应回环地址127.0.0.1,这类连接完全在内核内部完成,不需要经过物理网卡和外部网络链路。当尝试连接未开放的本地端口时,内核会直接返回ECONNREFUSED错误,这个过程瞬间完成,根本不会触发你设置的socket.settimeout()超时机制。而外部连接的未开放端口,需要等待TCP三次握手超时才会返回错误,这个过程受timeout限制。Linux内核的本地请求优化:Ubuntu基于Linux内核,内核对本地套接字请求有专门的优化逻辑。它会直接检查目标端口是否有进程在监听,没有的话立刻拒绝连接,不存在任何网络层面的等待延迟。而外部连接需要经过路由、防火墙、目标主机响应等多个环节,每个环节都会产生可观的延迟。
connect_ex()的行为差异:针对本地连接,connect_ex()调用能瞬间获取内核返回的结果(成功或拒绝),循环执行速度完全由内核处理能力决定;而外部连接的connect_ex()需要等待完整的网络交互流程,速度受timeout和网络环境影响。
内容的提问来源于stack exchange,提问作者maskalev
相关产品推荐
相关产品推荐

