单客户端-服务端基础聊天程序报错求助:AttributeError: _convert_
问题排查与修复方案
1. 核心导入错误:AttributeError: _convert_
从报错回溯能一眼看出问题所在:你的代码在导入socket模块时,没有加载Python标准库的socket,而是加载了你自己项目目录下的socket.py文件:
File "C:\Users\Abishek\AppData\Roaming\JetBrains\PyCharmCE2020.2\scratches\socket.py", line 64, in
Python的模块导入优先级是当前目录 > 标准库目录,你自己的socket.py和标准库模块重名了,导致导入逻辑混乱,触发了枚举类的错误。
解决方法:
- 立刻删除或重命名你项目目录下的
socket.py文件(绝对不要和标准库模块名重复) - 清理该目录下生成的
__pycache__文件夹(如果存在的话),避免缓存干扰 - 重新运行客户端和服务端,此时会正确导入标准库的
socket模块
2. 代码中的其他逻辑错误与修复
解决导入问题后,你的代码还有几个关键逻辑问题需要修正,否则聊天功能无法正常工作:
客户端(client1.py)的问题修复
- 线程传参错误:
threading.Thread的args参数必须是元组,你直接传client_name会把字符串拆成单个字符作为参数传递 - DISCONNECT_MSG逻辑错误:
'break' or 'disconnect'的结果永远是'break',无法匹配disconnect指令 - 接收消息的循环逻辑:当连接被主动关闭时,
recv()会返回空值,需要处理这种情况退出循环
修复后的关键代码片段:
# 修正断开指令的判断逻辑 DISCONNECT_MSG = ['break', 'disconnect'] def send_msg(client_name): connected = True while connected: message = input('>>> ') client_info_with_msg = f'[{client_name}: {message}]' sock.send(client_info_with_msg.encode(FORMAT)) # 匹配任意断开指令 if message.lower() in DISCONNECT_MSG: print(f'{client_name} DISCONNECTED!!') connected = False def recv_msg(): run = True while run: try: recv_message = sock.recv(512) if not recv_message: # 连接关闭时recv返回空 run = False break message = recv_message.decode('utf-8') print(f'{message}') # 判断是否包含断开指令 if any(msg in message.lower() for msg in DISCONNECT_MSG): run = False except Exception as e: print(f"接收消息出错: {e}") run = False def main(server,port): connection(server, port) client_name = input("Enter your name: ") # 线程传参必须是元组(注意末尾的逗号) thread1 = threading.Thread(target=send_msg, args=(client_name,)) thread1.start() thread2 = threading.Thread(target=recv_msg) thread2.start() thread1.join() thread2.join() sock.close()
服务端(chatserver.py)的问题修复
- connection函数逻辑错误:服务端不需要调用
sock.connect(ADDR),这是客户端的操作,服务端只需要绑定端口并监听 - 端口不一致:客户端用的是
port=8080,服务端用的是port=4444,两端端口必须统一 - 接收缓冲区太小:
buffer_size=128可能导致消息被截断,建议调大到512或1024 - 断开指令不统一:服务端的
Disconnect_msg和客户端的指令不匹配,需要同步
修复后的关键代码片段:
# 统一端口为8080(和客户端保持一致) port = 8080 # 调大接收缓冲区 buffer_size = 512 # 统一断开指令 Disconnect_msg = ['break', 'disconnect'] # 替换错误的connection函数,改为正确的客户端连接处理逻辑 def handle_client(conn, addr): print(f"[NEW CONNECTION] {addr} connected.") connected = True while connected: try: recv_msg = conn.recv(buffer_size).decode(format) if not recv_msg: print(f"[CONNECTION CLOSED] {addr} disconnected.") connected = False break print(f"[MESSAGE FROM {addr}] : {recv_msg}") # 判断是否包含断开指令 if any(msg in recv_msg.lower() for msg in Disconnect_msg): print(f"[CLIENT DISCONNECTED] {addr}") connected = False except Exception as e: print(f"处理客户端消息出错: {e}") connected = False conn.close() if __name__ == '__main__': sock.bind(ADDR) sock.listen(5) print(f'Server IP: {SERVER}') print('Waiting for connection...') conn , addr = sock.accept() # 启动处理客户端的线程 client_thread = threading.Thread(target=handle_client, args=(conn, addr)) client_thread.start() client_thread.join() sock.close()
3. 最终运行步骤
- 确认已删除/重命名自己的
socket.py文件,清理__pycache__文件夹 - 先运行服务端
chatserver.py,记下输出的Server IP - 运行客户端
client1.py,输入服务端IP,再输入用户名 - 现在可以在客户端输入消息,服务端会实时接收;输入
break或disconnect即可断开连接
内容的提问来源于stack exchange,提问作者Abishek
相关产品推荐
相关产品推荐

