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

Python套接字多客户端连接报错[WinError 10061]解决方案咨询

解决套接字服务器无法支持多客户端的问题

嘿,我来帮你搞定这个问题!首先得明确你遇到的核心问题:你的服务器代码只调用了一次s.accept(),这意味着它只能接受第一个客户端的连接,之后就停在那里了,根本没在监听新的连接请求——这就是第二个客户端连不上报[WinError 10061]的原因。设置s.setblocking(False)只是改变单个socket的阻塞行为,但没解决“只接受一次连接”的本质问题。

下面给你两种适合新手的解决方案,你可以根据需求选择:

方案1:多线程处理(简单易上手)

每个客户端连接进来后,我们启动一个独立线程处理它的交互,主线程继续回到accept()等待新连接,这样就能同时支持多个用户了。

修改后的服务器代码示例:

import socket
import threading
from your_module import ClientServidor  # 导入你的ClientServidor类

def handle_client(client):
    # 用你的ClientServidor类处理客户端逻辑
    print(f"新客户端连接:{client.addr}")
    try:
        # 假设你的ClientServidor有run()方法处理交互逻辑
        client.run()
    finally:
        client.conn.close()
        print(f"客户端连接关闭:{client.addr}")

def server():
    HOST = ''
    PORT = 50000
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(5)
    print(f"服务器启动,监听端口{PORT}...")
    
    try:
        while True:
            # 循环等待新连接,这是解决问题的关键!
            conn, addr = s.accept()
            # 创建你的ClientServidor实例
            client = ClientServidor(conn, addr)
            # 启动线程处理该客户端
            client_thread = threading.Thread(target=handle_client, args=(client,))
            client_thread.daemon = True  # 主线程退出时自动终止子线程
            client_thread.start()
    except KeyboardInterrupt:
        print("服务器正在关闭...")
    finally:
        s.close()

if __name__ == "__main__":
    server()

方案2:IO多路复用(适合高并发场景)

如果不想用多线程,也可以用Python的selectors模块实现单线程处理多客户端,这种方式资源占用更低,适合高并发场景。

示例代码:

import socket
import selectors
from your_module import ClientServidor  # 导入你的ClientServidor类

sel = selectors.DefaultSelector()

def accept_new_connection(sock):
    conn, addr = sock.accept()
    print(f"新客户端连接:{addr}")
    conn.setblocking(False)
    # 创建ClientServidor实例并注册到选择器
    client = ClientServidor(conn, addr)
    # 监听客户端socket的可读事件(假设你的ClientServidor需要处理读事件)
    sel.register(conn, selectors.EVENT_READ, data=client)

def handle_client_event(key, mask):
    client = key.data
    sock = key.fileobj
    try:
        # 假设你的ClientServidor有handle_read()方法处理收到的数据
        client.handle_read()
        # 如果客户端断开连接,取消注册并关闭socket
        if not client.is_connected():
            sel.unregister(sock)
            sock.close()
            print(f"客户端连接关闭:{client.addr}")
    except Exception as e:
        print(f"处理客户端{client.addr}时出错:{e}")
        sel.unregister(sock)
        sock.close()

def server():
    HOST = ''
    PORT = 50000
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((HOST, PORT))
    s.listen(5)
    s.setblocking(False)
    # 注册服务器socket的可读事件(监听新连接)
    sel.register(s, selectors.EVENT_READ, data=None)
    print(f"服务器启动,监听端口{PORT}...")
    
    try:
        while True:
            # 阻塞等待事件发生
            events = sel.select(timeout=None)
            for key, mask in events:
                if key.data is None:
                    # 处理新连接
                    accept_new_connection(key.fileobj)
                else:
                    # 处理已连接客户端的事件
                    handle_client_event(key, mask)
    except KeyboardInterrupt:
        print("服务器正在关闭...")
    finally:
        sel.close()
        s.close()

if __name__ == "__main__":
    server()

关键总结

你原来的代码只调用了一次s.accept(),服务器在接受第一个连接后就不再监听新请求了——这是问题的核心。只要让服务器循环调用s.accept(),同时用多线程或IO多路复用处理已连接客户端的交互,就能解决多客户端连接的问题。

内容的提问来源于stack exchange,提问作者Pol Marín

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:28:35