Python3多进程结合SSL安全套接字出现WinError10038错误求助
解决Windows下multiprocessing结合SSL套接字的WinError 10038问题
这个错误的核心原因是Windows系统下multiprocessing的spawn启动机制和SSL套接字的跨进程兼容性问题:
Windows默认用spawn方式创建子进程,这种方式会启动全新的Python解释器并重新加载主模块。如果你直接把已经包装好的secure_socket传给子进程,这个套接字对象在子进程中无法正确映射到有效的系统套接字句柄,就会被判定为“非套接字对象”,触发WinError 10038。
修复方案:在子进程中完成SSL套接字包装
正确的做法是:主进程只传递原始的客户端套接字给子进程,在子进程内部再执行SSL包装操作。这样子进程拿到的是有效的套接字句柄,能正常完成SSL握手。
修改后的代码示例:
import socket import ssl import multiprocessing IP = "0.0.0.0" PORT = 4433 def handle_client(client_socket, arg1, arg2): # 子进程内部完成SSL套接字包装 try: secure_socket = ssl.wrap_socket( client_socket, server_side=True, ca_certs="client.pem", certfile="server.pem", keyfile="server.key", cert_reqs=ssl.CERT_REQUIRED, ssl_version=ssl.PROTOCOL_TLSv1_2 ) # 这里执行你的业务逻辑,比如myfunc的内容 print(f"Connected securely with {secure_socket.getpeername()}") # 示例:接收并发送数据 data = secure_socket.recv(1024) if data: secure_socket.send(b"Received your message via secure channel") except Exception as e: print(f"Client handling error: {str(e)}") finally: # 确保套接字关闭 if 'secure_socket' in locals(): secure_socket.close() client_socket.close() if __name__ == "__main__": # 主进程创建监听套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 允许地址重用,避免重启服务器时的端口占用问题 server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((IP, PORT)) server_socket.listen(5) print(f"Secure server listening on {IP}:{PORT}") while True: client_socket, client_addr = server_socket.accept() print(f"Accepted unsecure connection from {client_addr}") # 启动子进程,传递原始客户端套接字和参数 worker_process = multiprocessing.Process( target=handle_client, args=(client_socket, "arg1_value", "arg2_value") ) worker_process.start() # 主进程关闭套接字引用,让子进程接管所有权 client_socket.close()
额外注意事项
- 必须加
if __name__ == "__main__"保护:Windows的spawn机制会重新导入主模块,没有这个判断的话,代码会重复执行监听逻辑,导致异常。 - 主进程及时关闭客户端套接字:子进程启动后,主进程不再需要持有client_socket的引用,关闭它可以避免资源泄漏。
- 证书路径正确性:确保子进程能访问到
client.pem、server.pem等证书文件,建议使用绝对路径。
内容的提问来源于stack exchange,提问作者AgentsOfShield
相关产品推荐
相关产品推荐

