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

Python使用socket开发时无法同时向两个客户端发送数据如何解决?

问题原因分析

核心问题点

  • 你的服务端每个客户端连接对应的handle_client线程中都调用了阻塞式的input()函数,stdin输入是全局共享的资源,只有第一个启动的客户端线程能抢到输入权限,后续线程都会卡在input()等待,永远拿不到要发送的内容,所以只有第一个连接的客户端能收到消息
  • 没有统一的消息广播机制,每个客户端线程独立处理输入,本身逻辑就不符合“服务端发消息给所有客户端”的需求
修复方案

你需要把控制台输入逻辑和客户端处理逻辑拆分,新增全局连接池管理所有在线客户端,单独启动一个线程处理控制台输入,将输入的消息广播给所有在线客户端。

修正后的服务端完整代码

import socket
import threading
import time

HEADER = 2048
PORT = 4444
SERVER = "你的服务端IP" # 替换为你的实际IP
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "dc"

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(ADDR)

# 全局连接池存储所有在线客户端套接字
connected_clients = []
# 线程锁,避免多线程操作连接池出现冲突
lock = threading.Lock()

def broadcast_msg():
    """单独线程处理控制台输入,广播消息给所有在线客户端"""
    while True:
        comman = input("message: ")
        with lock:
            # 遍历所有连接发送消息,用copy避免遍历过程中列表修改报错
            for conn in connected_clients.copy():
                try:
                    conn.send(comman.encode(FORMAT))
                except:
                    # 发送失败说明客户端已断开,移除连接
                    connected_clients.remove(conn)

def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected.")
    # 新客户端加入连接池
    with lock:
        connected_clients.append(conn)
    try:
        while True:
            # 监听客户端消息,处理断开连接请求
            msg = conn.recv(HEADER).decode(FORMAT)
            if msg == DISCONNECT_MESSAGE:
                break
    finally:
        # 客户端断开后清理连接
        with lock:
            if conn in connected_clients:
                connected_clients.remove(conn)
        conn.close()
        print(f"[DISCONNECT] {addr} disconnected, 剩余在线连接数: {len(connected_clients)}")

def start():
    # 先启动广播消息线程
    threading.Thread(target=broadcast_msg, daemon=True).start()
    server.listen()
    print(f"[LISTENING] Server is listening on {SERVER}")
    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        print(f"[ACTIVE CONNECTIONS] {len(connected_clients)}")

print("server is starting...")
start()

客户端优化建议

现有客户端代码可以正常运行,仅需注意函数名recieve拼写应为receive,不影响实际执行。建议增加异常捕获逻辑,避免服务端断开时客户端直接崩溃:

def recieve():
    while True:
        try:
            print(client.recv(2048).decode(FORMAT))
        except:
            print("与服务端断开连接")
            client.close()
            break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 21:36:07