Python Socket超时未收到数据时如何关闭连接
问题根因
你的代码有3处错误导致超时逻辑不生效:
- 超时设置对象错误:
s.settimeout(1.0)是给监听套接字设置超时,仅会影响s.accept()的等待时长,和后续收发数据的连接套接字conn无关,因此conn.recv()不会触发1秒超时。 - 变量拼写错误:接收数据时赋值的变量是
received,后续空值判断时错写为recieved,代码运行到判断逻辑会直接抛出NameError。 - 超时处理逻辑缺失:套接字超时会抛出
socket.timeout异常,你没有编写对应的异常捕获分支,自然无法执行超时关连接的逻辑;当前Python版本中socket.timeout属于socket模块的内置异常,不需要额外做子模块导入。
修复后代码
import socket import time HOST = "127.0.0.1" PORT = 3999 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind((HOST, PORT)) s.listen() conn, addr = s.accept() # 超时配置要设置在实际负责通信的连接对象上 conn.settimeout(1.0) with conn: print(f"Connected by {addr}") while True: start = time.time() try: received = conn.recv(1024) end = time.time() # 修复变量拼写错误 if not received: print("客户端主动断开连接") break print(f"I got '{received.decode()}'") except socket.timeout: end = time.time() print(f"等待数据超时,共等待{round(end-start, 2)}秒,自动关闭连接") break
逻辑说明
- 超时配置绑定到
conn对象后,recv()调用如果1秒内没有收到任何数据,会立即抛出socket.timeout异常 - 触发超时异常后直接跳出通信循环,
with conn上下文管理器会自动完成连接关闭操作,不需要手动调用close() - 原代码把
import time写在循环内部会造成无意义的重复导入,已经调整到文件顶部 - 当
recv()返回空字节时,代表客户端主动正常断开连接,此时也直接跳出循环释放资源
内容的提问来源于stack exchange,提问作者vojtam
相关产品推荐
相关产品推荐

