Windows下Socket编程出现WinError 10061和WinError 10022错误
Windows下Python Socket绑定端口失败问题分析
问题背景
一段实现"先尝试连接端口,失败则绑定端口作为服务器"的Python Socket代码,在Ubuntu、CentOS上可正常运行,但在Windows 10上报错。已关闭防火墙和杀毒软件,问题仍存在。拆分客户端和服务器代码为两个文件可解决,但疑惑为何原代码的try-except逻辑在Windows上失效。
原代码
import socket port = 9999 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = socket.gethostname() try: s.connect((host,port)) except: s.bind((host, port)) s.listen(1) print("I'm a server") clientsocket, address = s.accept() else: print("I'm a client")
Windows 10报错信息
Traceback (most recent call last): File "win.py", line 11, in <module> s.connect((host,port)) ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it During the handling of the above exception, another exception occurred: Traceback (most recent call last): File "win.py", line 13, in <module> s.bind((host, port)) OSError: [WinError 10022] An invalid argument was supplied
问题原因与解决方案
核心原因
不是try-except逻辑本身的问题,而是Windows与Linux的Socket内核实现差异:
- Linux系统对Socket状态限制宽松,允许调用过
connect()的Socket后续执行bind()操作; - Windows对Socket状态的限制更严格:调用
connect()后,Socket进入"连接尝试/已连接"状态,Windows内核不允许该状态的Socket再执行绑定端口的操作,因此触发WinError 10022无效参数错误。
解决方案
不要复用同一个Socket对象,而是在连接失败后,重新创建一个新的Socket来实现服务器绑定逻辑。修改后的代码如下:
import socket port = 9999 host = socket.gethostname() # 尝试客户端连接 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client_socket.connect((host, port)) print("I'm a client") except ConnectionRefusedError: # 连接失败,创建新Socket作为服务器 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) server_socket.listen(1) print("I'm a server") clientsocket, address = server_socket.accept() finally: client_socket.close()
这样客户端和服务器使用独立的Socket对象,各自处于正确的状态,就能在Windows和Linux上都正常运行。
内容的提问来源于stack exchange,提问作者Ehsan
相关产品推荐
相关产品推荐

