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
相关产品推荐
相关产品推荐

