聊天应用私有群组功能异常:加入后崩溃,离开后无法发消息
多人聊天应用群组功能崩溃及消息发送问题修复
问题根源
- 加入群组后崩溃:
Group.remove_member方法在成员未存在于群组时调用set.remove()会触发KeyError,导致线程崩溃;同时消息发送逻辑未区分"群组内"和"全局"场景。 - 离开群组后无法发消息:离开群组后代码未恢复全局广播逻辑,且客户端未同步更新状态提示。
修复方案
1. 修复Group类的移除成员方法(避免崩溃)
修改server.py中的Group类remove_member方法,先检查成员是否存在再执行删除:
def remove_member(self, client_handler): with groups_lock: if client_handler in self.members: self.members.remove(client_handler)
2. 调整消息发送逻辑(区分群组/全局)
在server.py的消息处理循环中,替换原全局广播代码,根据用户是否在群组内选择发送目标:
# 替换原有的全局广播代码段 if not message or message == "/exit": break current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') broadcast_message = f"[{current_time}] {self.username}: {message}" if self.group: # 处于群组内,仅发送给群成员 self.group.send_to_all(broadcast_message, self) else: # 未加入群组,全局广播 with clients_lock: for usr, client in clients.items(): if usr != self.username: client.send(broadcast_message.encode('utf-8'))
3. 客户端显示当前房间(用户名旁标注群组)
修改client.py,新增群组状态跟踪,并在输入提示中展示:
def start_client(host, port): try: client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((host, port)) message_lock = threading.Lock() current_group = None # 新增:跟踪当前群组状态 except ConnectionRefusedError as e: if e.errno == 111: print("Connection refused") else: print(f"An unknown error occurred {e}") return # 保留原有获取用户名的代码... # 修改监听服务器消息的函数,同步群组状态 def listen_to_server(): nonlocal username, current_group while True: data = client_socket.recv(1024).decode('utf-8') if not data: break with message_lock: # 更新群组状态 if "Joined group '" in data: current_group = data.split("Joined group '")[1].rstrip("'.") elif "Left group '" in data: current_group = None # 更新用户名 if "Username changed to " in data: username = data.split("Username changed to ")[1].rstrip(".") # 构建带群组的提示文本 prompt = f"{username}" if current_group: prompt += f" [{current_group}]" prompt += f":{Fore.YELLOW} Enter your message: {Style.RESET_ALL}" print(f"{Fore.GREEN}\n{data}\n{Style.RESET_ALL}{prompt}", end='') threading.Thread(target=listen_to_server, daemon=True).start() # 修改输入循环的提示文本 while True: try: prompt = f"{username}" if current_group: prompt += f" [{current_group}]" prompt += f": {Fore.YELLOW}Enter your message: {Style.RESET_ALL}" print(prompt, end='') message = input() # 保留原有消息发送逻辑...
4. 优化群组命令的参数处理(可选)
避免用户输入不带密码的群组命令时出现分割错误,修改server.py中/creategroup和/joingroup的处理:
# 修改/creategroup处理 if message.startswith("/creategroup "): parts = message.split(maxsplit=2) if len(parts) < 2: self.client_socket.send("Usage: /creategroup [group_name] [password (optional)]".encode('utf-8')) continue group_name = parts[1] password = parts[2] if len(parts) > 2 else "" hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest() if password else None # 保留原有群组创建逻辑... # 修改/joingroup处理 if message.startswith("/joingroup "): parts = message.split(maxsplit=2) if len(parts) < 2: self.client_socket.send("Usage: /joingroup [group_name] [password (if required)]".encode('utf-8')) continue group_name = parts[1] password = parts[2] if len(parts) > 2 else "" hashed_password = hashlib.sha256(password.encode('utf-8')).hexdigest() if password else None # 保留原有群组加入逻辑...
内容的提问来源于stack exchange,提问作者user12328867
相关产品推荐
相关产品推荐

