Python socket多客户端通信故障:第二客户端发首条消息后无法收发
问题根因
服务端threaded函数存在变量名重复覆盖问题:
- 函数入参
conn是当前线程绑定的客户端连接对象,用于接收该客户端发送的消息 - 广播消息的循环复用了
conn作为遍历变量:for conn in client_socket,第一次广播完成后,原入参conn会被覆盖为client_socket中最后一个客户端的连接 - 后续线程再执行
conn.recv(1024)时,实际是在监听最后一个客户端的消息,其余客户端的消息都不会被处理,就出现了你遇到的问题。
修复方案
仅需要修改服务端广播循环的变量名即可解决核心问题,同时可以补充几个优化点避免后续报错:
- 广播循环变量改为
client,不覆盖原连接对象 - 客户端断开连接时从
client_socket集合中移除该连接,避免广播给无效连接 - 广播时跳过发送方自身,减少无效传输也不需要客户端再做重复消息过滤
修复后服务端完整代码
import socket from _thread import * import sys HOST = "127.0.0.1" PORT = 12000 client_socket = set() def threaded(conn): while True: try: data = conn.recv(1024).decode() if not data: print("Lost connection") break # 遍历变量改用client,不覆盖原conn for client in client_socket: # 跳过发送者自身,不用客户端过滤重复消息 if client != conn: client.send(data.encode()) except Exception as e: print(f"Connection error: {e}") break # 断开后从集合中移除连接 client_socket.remove(conn) print("Gone") conn.close() s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(5) print("Server is up and running") while True: conn, addr = s.accept() print("Connected to", addr) client_socket.add(conn) start_new_thread(threaded, (conn, ))
客户端可选优化
服务端已经跳过发送方自身后,客户端可以删除多余的check变量逻辑:
import threading import socket, sys HOST = "127.0.0.1" PORT = 12000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) def background(): while True: answer = s.recv(1024).decode() if answer: print(answer) threading1 = threading.Thread(target=background) threading1.daemon = True threading1.start() while True: message = input() if message: s.send(message.encode())
内容的提问来源于stack exchange,提问作者Kulegutten
相关产品推荐
相关产品推荐

