You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单客户端-服务端基础聊天程序报错求助: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. 最终运行步骤

  1. 确认已删除/重命名自己的socket.py文件,清理__pycache__文件夹
  2. 先运行服务端chatserver.py,记下输出的Server IP
  3. 运行客户端client1.py,输入服务端IP,再输入用户名
  4. 现在可以在客户端输入消息,服务端会实时接收;输入break或disconnect即可断开连接

内容的提问来源于stack exchange,提问作者Abishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:47:47