You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:26:04