跨设备聊天服务器Socket发送数据时连接断开问题求助
解决Socket聊天服务器连接后发送数据断开的问题
咱们先梳理下你的问题:初始能建立连接,但客户端立刻报错OSError: [Errno 57] Socket is not connected,服务器后续发消息会触发ConnectionResetError,核心问题全在客户端代码的逻辑错误上,咱们一步步拆解修复:
问题根源分析
portConnect函数的递归死循环+未保留连接Socket
当客户端成功连接服务器后,你又调用了portConnect(h_name,port),这会无限递归,而且没有把成功连接的Socket对象保存下来,后续while1函数根本拿不到可用的连接。while1函数重复创建未连接的Socket
每次循环都新建x = socket.socket(),这个全新的Socket根本没和服务器建立连接,调用recv自然会报错“Socket is not connected”。- Socket对象未在函数间传递
连接成功的Socket没有传递到while1,导致收发数据用的都是未连接的新Socket,直接触发断开。
修复后的客户端代码
import socket import sys import time def getHostName(): return input(str("Enter the hostname of the server: ")) def portConnect(h_name, start_port): port = start_port while True: try: x = socket.socket() x.connect((h_name, port)) print(f"Connected to chat server on port {port}") return x # 返回已连接的socket对象 except ConnectionRefusedError: print(f'Port {port} is incorrect, trying port {port+1}...') port += 1 if port > 65535: print("No available ports found, exiting...") sys.exit() def chat_loop(connected_socket): while True: try: # 接收服务器消息 incoming_message = connected_socket.recv(1024) if not incoming_message: print("Server disconnected") break incoming_message = incoming_message.decode() print(" Server :", incoming_message) # 发送消息 message = input(str(">>")) if message == 'QUIT': confirmation = input('Are you sure you would like to quit (Y/N)? ') if confirmation.strip().upper() == 'Y': print('Press enter to quit...') connected_socket.close() # 关闭连接 input() sys.exit() # 编码并发送消息 message = message.encode() connected_socket.send(message) print("Message has been sent...") except OSError as e: print(f'Error: {e}, please check if the server is running') cont = input('Would you like to quit or continue (Q/C): ') if cont.strip().upper() == 'C': h_name = getHostName() connected_socket = portConnect(h_name, 8000) else: connected_socket.close() print('Press enter to exit') input() sys.exit() # 主流程 h_name = getHostName() connected_socket = portConnect(h_name, 8000) chat_loop(connected_socket)
关键修复点说明
portConnect返回已连接的Socket:把成功建立连接的Socket对象返回给主流程,确保后续聊天能用同一个连接。- 去掉递归调用:连接成功后直接返回Socket,不再重复调用自身,避免死循环。
chat_loop复用连接Socket:接收已连接的Socket作为参数,全程用这个Socket收发数据,不再新建未连接的Socket。- 增加断开判断:当
recv返回空字节时,说明服务器已断开,主动退出循环。 - 规范资源关闭:退出时关闭Socket,避免资源泄漏。
你的服务器代码是正常的,修复客户端后,就能实现服务器先发消息、双方轮流收发的功能了。
内容的提问来源于stack exchange,提问作者user14303139
相关产品推荐
相关产品推荐

