如何排查Python TCP服务端OSError: [Errno 9] Bad file descriptor错误
错误原因
OSError: [Errno 9] Bad file descriptor完全由服务端代码的逻辑错误导致:
- 你将
conn.close()写在了while True循环内部,第一次循环处理完客户端请求并返回结果后,就直接关闭了和客户端通信的连接套接字conn - 循环进入第二次迭代时,程序会尝试调用已经被关闭的
conn执行recv操作,操作系统直接抛出无效文件描述符的错误 - 额外逻辑缺陷:当前服务端仅执行一次
accept(),只能处理单个客户端连接,处理完成后无法接收新的客户端请求
修复方案
适配单次请求场景
如果你的客户端只会发起一次请求后就退出,直接移除服务端的while True循环即可,修复后代码如下:
# This is add_server.py script import socket host = socket.gethostname() port = 8096 s = socket.socket() s.bind((host, port)) s.listen(5) print('Waiting for connection...') conn, addr = s.accept() data = conn.recv(1024) print(data) decoded_data = data.decode('utf-8') d = decoded_data.split(",") # 额外添加strip处理客户端拼接产生的前缀空格,避免int转换报错 add_data = int(d[0].strip()) + int(d[1].strip()) conn.sendall(str(add_data).encode('utf-8')) conn.close() s.close()
常规TCP服务端写法(支持多客户端、单客户端多次请求)
将accept()逻辑移到外层循环,内层循环处理单个连接的所有请求,客户端断开后再关闭连接:
# This is add_server.py script import socket host = socket.gethostname() port = 8096 s = socket.socket() s.bind((host, port)) s.listen(5) print('Waiting for connection...') while True: conn, addr = s.accept() print(f"收到来自{addr}的新连接") while True: data = conn.recv(1024) # recv返回空字节代表客户端已断开连接 if not data: break decoded_data = data.decode('utf-8') d = decoded_data.split(",") add_data = int(d[0].strip()) + int(d[1].strip()) conn.sendall(str(add_data).encode('utf-8')) conn.close()
内容的提问来源于stack exchange,提问作者sam hassan
相关产品推荐
相关产品推荐

