如何解决Python Socket TCP聊天室发送者重复收消息的问题?
解决TCP聊天室发送者终端重复显示消息的问题
问题描述
使用Python的socket模块搭建TCP聊天室时,遇到一个bug:客户端发送消息后,发送者自己的终端会重复显示这条消息。
问题原因
- 客户端过滤逻辑失效:客户端原本通过
name == mes[0:(len(name)+1)]判断是否为自己的消息,但实际发送的消息格式是\n{name} : {message_to_send},消息开头带有换行符,导致截取的字符串与name不匹配,过滤条件永远不成立。 - 服务器广播未排除发送者:服务器收到消息后,会将消息广播给所有连接的客户端,包括发送这条消息的客户端本身,因此发送者会收到自己发出的消息。
修复方案
方案一:修正客户端消息过滤逻辑
修改receive_data函数中的判断条件,正确识别自己发送的消息:
# Receive data from server def receive_data(): while True: try: mes = client.recv(1024).decode('ascii') # If the message is 'name', send name to server if mes == 'name': client.send(name.encode('ascii')) # 修正判断:去除开头换行后,检查是否以自己的name加冒号开头 elif mes.lstrip('\n').startswith(f"{name} :"): pass # Otherwise it will print the message else: print(mes) except: # Close the connection print(f"{colours.Colours.red}An error occurred!{colours.Colours.end}") client.close() break
方案二:修改服务器广播逻辑,排除发送者
调整服务器的broadcast函数,跳过发送消息的客户端,避免将消息回传给发送者:
# 定义广播函数,传入发送者客户端用于排除 def broadcast(message, sender_client): for client in clients: if client != sender_client: client.send(message) # 修改handle_clients函数,传递发送者客户端 def handle_clients(client): while True: try: # Broadcasting messages mes = client.recv(1024) broadcast(mes, client) # 传入发送者client except: # Removing clients name = clients[client] broadcast(f"{colours.Colours.red}{name} has left!{colours.Colours.end}".encode('ascii'), client) del clients[client] break
两种方案任选其一即可,方案二更高效,能减少不必要的网络传输。
内容的提问来源于stack exchange,提问作者Sam Winkworth
相关产品推荐
相关产品推荐

