如何在socket.connect_ex连接后断开并重复获取0响应码?
解决重复使用socket.connect_ex的端口检测问题
问题原因
你遇到的错误码对应socket的状态问题:
- 错误码56:当前socket已处于已连接状态,TCP协议不允许对已连接的socket再次发起连接操作。
- 错误码9:socket已被
close()关闭,对应的文件描述符已失效,无法再用于任何网络操作。
TCP socket是有状态的,一旦完成连接或被关闭,该socket实例就无法再用于新的连接尝试。
解决方案:每次检测创建新socket实例
最可靠且简单的方式是,每次端口检测都创建一个全新的socket对象,检测完成后立即关闭。这样能确保每次connect_ex都是独立的连接尝试,返回正确的结果码。
示例代码
import socket def check_port(host: str, port: int, timeout: float = 1.0) -> bool: """检测指定主机的端口是否开放""" # 每次检测创建新的socket,用with语句自动管理资源 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.settimeout(timeout) # 设置超时,避免无响应时阻塞 result = sock.connect_ex((host, port)) return result == 0 # 重复检测示例 for attempt in range(3): if check_port('host', 22): print(f"Attempt {attempt+1}: Port is open") else: print(f"Attempt {attempt+1}: Port is not open")
关键说明
- 使用
with语句自动处理socket的关闭,无需手动调用close(),避免资源泄漏。 - 设置
timeout参数,防止因目标主机无响应导致程序长时间阻塞。 - 每次调用
check_port都会生成新的socket实例,彻底规避旧连接状态的干扰。
关于socket断开的正确操作
如果需要手动断开已连接的socket,应先调用sock.shutdown(socket.SHUT_RDWR)关闭读写通道,再调用sock.close()释放资源。但即使完成该操作,此socket实例也无法再次用于连接,因此仍建议每次检测创建新socket。
内容的提问来源于stack exchange,提问作者notacorn
相关产品推荐
相关产品推荐

