如何实现可中断的持久Socket连接?解决消息发送异常
持久化Socket连接实现方案
你的问题根源在服务端逻辑:当前服务端每接受一个客户端连接后,仅调用一次recv()就回到accept()等待新连接,导致客户端后续发送的消息无法被监听。要实现单连接下的持续通信,服务端需在建立连接后,循环接收该客户端的消息,直到连接断开或触发中断。
修改后的服务端代码
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('127.0.0.1', 8888)) s.listen(5) print("服务端启动,等待客户端连接...") try: while True: client, addr = s.accept() print(f"客户端 {addr} 已连接") # 持续接收当前客户端的消息 while True: try: res = client.recv(1024) if not res: # 客户端主动断开时,recv返回空字节 print(f"客户端 {addr} 已断开") client.close() break print(addr, 'says:', res.decode('utf-8')) except KeyboardInterrupt: print("\n收到中断信号,关闭所有连接") client.close() s.close() exit() except KeyboardInterrupt: print("\n服务端已关闭") s.close()
修改后的客户端代码
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('127.0.0.1', 8888)) print("已连接到服务端,输入'exit'断开连接,按Ctrl+C中断") try: while True: com = input('Enter the message: ') if com == 'exit': s.send(com.encode()) print('发送退出指令,断开连接') s.close() break s.send(com.encode()) print('消息已发送') except KeyboardInterrupt: print("\n收到中断信号,关闭连接") s.close()
核心改进点
- 服务端新增内层循环,在接受客户端连接后持续调用
recv(),直到客户端断开或触发中断,确保能接收所有后续消息。 - 客户端保持单次Socket初始化与连接,避免频繁创建连接的开销,同时添加
KeyboardInterrupt捕获逻辑,保证中断时能正确关闭Socket。 - 处理了客户端主动断开的场景(
recv()返回空字节),避免服务端阻塞。
内容的提问来源于stack exchange,提问作者Mihalych
相关产品推荐
相关产品推荐

