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

如何使用Python的socket与selectors实现多客户端之间的消息通信?

服务端改造实现多客户端消息互通的方案

核心问题说明

你当前的代码仅实现了单客户端echo逻辑,核心缺失两个能力:没有存储所有在线客户端的连接,收到消息后无法遍历转发给其他客户端;同时监听队列长度为1,最多仅支持1个客户端接入。

改造后的完整服务端代码

import selectors
import socket

sel = selectors.DefaultSelector()
# 新增:存储所有在线客户端的套接字集合
online_clients = set()

def accept(sock, mask):
    conn, addr = sock.accept()
    conn.setblocking(False)
    sel.register(conn, selectors.EVENT_READ, read)
    # 新增:新客户端接入加入集合
    online_clients.add(conn)
    print(f"新客户端接入:{addr},当前在线人数:{len(online_clients)}")

def read(conn, mask):
    try:
        data = conn.recv(1024)
        if data:
            # 改造:遍历所有在线客户端,转发消息
            for client in online_clients:
                # 不需要给发送方回显就保留该判断,需要回显直接去掉if判断即可
                if client != conn:
                    client.send(data)
        else:
            # 客户端主动断开连接
            raise ConnectionResetError
    except (ConnectionResetError, BrokenPipeError):
        # 清理断开的客户端资源
        sel.unregister(conn)
        online_clients.remove(conn)
        conn.close()
        print(f"客户端断开,当前在线人数:{len(online_clients)}")

sock = socket.socket()
sock.bind(('localhost', 1234))
# 改造:监听队列改大,支持多个客户端同时接入
sock.listen(10)
sock.setblocking(False)
sel.register(sock, selectors.EVENT_READ, accept)

print("服务端启动,监听端口1234...")
while True:
    events = sel.select()
    for key, mask in events:
        callback = key.data
        callback(key.fileobj, mask)

客户端调整建议

你当前的客户端是同步阻塞逻辑,发送完消息后才会接收返回,无法实时接收其他客户端主动推送的消息,建议新增子线程单独处理消息接收,示例如下:

import socket
import sys
import threading

def recv_msg(s):
    while True:
        try:
            data = s.recv(1024)
            if data:
                print(f"\n收到消息:{data.decode()}")
            else:
                break
        except:
            break

server_address = ('localhost', 1234) 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
print('connecting to %s port %s' % server_address) 
s.connect(server_address)

# 启动接收消息的子线程
threading.Thread(target=recv_msg, args=(s,), daemon=True).start()

# 以下为发送逻辑,可根据需求修改
messages = [b'Hi from client1',
            b'Good morning from client1',
            ] 
for message in messages:
    s.send(message)
    # 等待输入再发下一条,方便测试效果
    input("按回车发送下一条消息...")

s.close()

测试步骤

  • 先启动修改后的服务端
  • 依次启动多个客户端,每个客户端发送的消息会自动转发给其他所有在线客户端

内容的提问来源于stack exchange,提问作者AAAAAAbc

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:15:03