Python Socket线程报OSError: Transport endpoint is not connected
Python Socket 多线程报
Transport endpoint is not connected排查 报错本质是对未建立有效端到端连接的套接字执行了收发操作,代码中存在3个直接触发问题的逻辑错误:
- 套接字对象用错:
sendfunc线程函数中调用recv的对象是监听套接字soc_server,该套接字仅负责监听端口、接受新连接,不负责和具体客户端通信,所有和客户端的收发操作必须使用accept()返回的对应客户端连接套接字soc_client。对监听套接字调用recv是触发本次报错的直接原因。 - 线程传参与变量命名不规范:一是使用Python内置类型名
list作为自定义变量名,同时函数使用了可变默认参数list=[],该默认参数会被所有线程共享,必然出现多线程数据串扰问题;二是原代码线程传参逻辑未做边界处理,多连接场景下容易出现套接字对象引用错乱。 - 数据类型与收发逻辑错误:
sendall方法仅支持bytes类型参数,原代码else分支直接传入字符串f'hello from server'会触发类型错误;同时连续两次调用recv读取数据,第一次调用已经读走客户端发送的内容,第二次调用会因客户端发完数据后关闭连接读到空值,触发连接异常。
修正后服务端代码
import socket import threading soc_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) soc_port = 5053 soc_server.bind(('127.0.0.1', soc_port)) def handle_client(soc_client, client_addr, msg_cache): try: # 连接建立后先发送欢迎消息,匹配客户端启动后先收消息的逻辑 soc_client.sendall('hello from server'.encode('utf-8')) # 循环接收当前客户端发送的消息,全程使用当前连接专属的soc_client套接字 while True: data = soc_client.recv(1024) if not data: print(f"client {client_addr} disconnected") break text = data.decode('utf-8') msg_cache.append(text) print(f"received from {client_addr[0]}:{client_addr[1]}: {text}") soc_client.sendall(data) except Exception as e: print(f"connection with {client_addr} failed: {str(e)}") finally: # 连接结束后主动关闭套接字释放资源 soc_client.close() soc_server.listen(5) print(f"server started, listening on 127.0.0.1:{soc_port}") shared_msg_cache = [] # 循环接受客户端连接,每个连接启动独立线程处理 while True: soc_client, addr = soc_server.accept() print('connected to : ' + addr[0]) client_thread = threading.Thread( target=handle_client, daemon=False, args=(soc_client, addr, shared_msg_cache) ) client_thread.start()
修正后客户端代码
import socket soc_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) soc_port = 5053 soc_client.connect(('127.0.0.1', soc_port)) # 接收服务端欢迎消息 welcome_msg = soc_client.recv(1024) print(welcome_msg.decode('utf-8')) # 发送测试消息 soc_client.sendall(b'hello from client') soc_client.close()
内容的提问来源于stack exchange,提问作者Sha256
相关产品推荐
相关产品推荐

