使用Socket与Threading搭建聊天室:客户端连接后服务器停止运行
问题排查与修复方案
服务器端(server.py)核心问题及修复
未定义变量触发崩溃
代码中定义了存储客户端连接的列表client_conns,但新客户端连接时却调用了clients.append(conn),clients变量未定义,直接触发NameError导致服务器终止运行。使用废弃的线程创建接口
threading._start_new_thread是Python已废弃的底层线程接口,稳定性差,推荐使用标准的threading.Thread类创建线程。未处理客户端断开场景
客户端断开时,conn.recv()会返回空字节串,若不处理会导致后续广播报错,需及时将异常连接从列表移除并关闭。广播未做异常捕获
部分客户端连接异常时,直接调用conn.send()会抛出错误中断广播流程,需添加异常处理保证广播正常执行。
修复后的server.py代码:
import socket import threading host = socket.gethostbyname(socket.gethostname()) port = 5000 client_conns = [] s = socket.socket() s.bind((host, port)) s.listen(10) def broadcast_msg(msg, sender_conn): for conn in client_conns: # 广播时排除消息发送者 if conn != sender_conn: try: conn.send(msg) except: # 移除异常连接并关闭 client_conns.remove(conn) conn.close() def handle_client(conn, addr): while True: try: msg = conn.recv(4096) if not msg: # 客户端主动断开 client_conns.remove(conn) conn.close() print(f"Connection closed: {addr}") break broadcast_msg(msg, conn) except: # 处理连接异常 client_conns.remove(conn) conn.close() print(f"Connection error: {addr}") break while True: conn, address = s.accept() print(f"Connection from: {address}") client_conns.append(conn) # 使用标准线程创建方式 thread = threading.Thread(target=handle_client, args=(conn, address)) thread.start()
客户端(client.py)问题及修复
原客户端发送消息后会阻塞在recv(),因为服务器广播不会发给消息发送者。修改后用单独线程处理消息接收,避免输入卡顿:
修复后的client.py代码:
import socket import threading def receive_messages(s): while True: try: data = s.recv(4096).decode() if data: print("\n" + data) except: print("Connection closed") s.close() break def client(): host = socket.gethostbyname(socket.gethostname()) port = 5000 s = socket.socket() s.connect((host, port)) alias = input("Alias: ") # 启动独立线程接收消息,避免阻塞输入 receive_thread = threading.Thread(target=receive_messages, args=(s,)) receive_thread.start() while True: message = input(f"{alias}: ") if message.lower() == 'quit': s.close() break message = alias + ": " + message s.send(message.encode()) client()
关键修复说明
- 服务器端修正变量名错误,改用标准线程API,添加连接异常处理与断开清理逻辑
- 客户端新增消息接收线程,解决输入阻塞问题,增加退出命令
内容的提问来源于stack exchange,提问作者LocalDogeCoder
相关产品推荐
相关产品推荐

