如何检测Socket是否仍连接?解决客户端断开后服务器异常循环问题
问题分析与解决方案
首先你的代码存在几个基础问题需要先修正:
s.listen(10)应该放在accept()之前,只需调用一次,不需要放到循环里- 代码使用了
time.sleep()但未导入time模块,会触发报错 - 当前逻辑未检测客户端连接状态,导致客户端断开后循环仍持续执行
检测客户端断开的核心逻辑
TCP连接中,判断客户端是否断开主要依赖两种场景:
recv()返回空字节串:当客户端主动调用close()断开连接时,服务器端的recv()会返回b''- 捕获连接异常:如果客户端异常断开(比如强制关闭进程),调用
recv()或send()时会抛出ConnectionResetError类异常
修正后的完整代码
import socket import time ip = '127.0.0.1' # 修正无效回环地址,127.1.0.0无法正常监听 port = 2400 # 创建socket并完成绑定 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((ip, port)) s.listen(10) # listen仅需调用一次 print(f"服务器已启动,等待客户端连接...") while True: # 等待新客户端接入 clientsocket, address = s.accept() print(f"客户端 {address[0]}:{address[1]} 已连接") # 处理当前客户端的消息循环 try: while True: msg = clientsocket.recv(8196) # 判断客户端主动断开 if not msg: print(f"客户端 {address[0]}:{address[1]} 主动断开连接") break print(f"收到 {address[0]}:{address[1]} 的消息: {msg.decode()}\n") time.sleep(0.05) except ConnectionResetError: print(f"客户端 {address[0]}:{address[1]} 异常断开连接") finally: # 无论正常/异常断开,都关闭客户端socket clientsocket.close() print(f"已关闭与 {address[0]}:{address[1]} 的连接")
关键说明
- 采用两层循环结构:外层循环等待新客户端连接,内层循环处理当前客户端的消息交互
- 通过
if not msg直接判断客户端主动断开的情况,这是TCP协议原生的断开通知机制 - 用
try-except捕获客户端异常断开的场景,确保socket能被正常关闭 - 修正了回环地址的错误,
127.1.0.0不是有效的回环地址,改为127.0.0.1才能正常监听
你之前尝试用send()检测连接的问题,大概率是误用了服务器主sockets而非客户端的clientsocket,且盲目发送可能触发不必要的异常。优先通过recv()返回值判断是更可靠的方案。
内容的提问来源于stack exchange,提问作者Greeger M
相关产品推荐
相关产品推荐

