Python3 Socket Server在sock.recv()阶段无法发送FIN/ACK的问题
Socket连接异常排查与修复
问题分析
客户端发送FIN关闭请求后,服务端通过recv()收到空字节流(b"")检测到了断开,但执行client.close()和sock.close()后仍无法回复FIN/ACK,核心问题出在代码逻辑错误:
- 错误关闭了监听socket(
self.sock):监听socket负责接收新连接,与当前客户端连接的client socket是独立的,关闭监听socket不仅多余,还会干扰正常连接流程。 - 关闭socket的顺序错误:应优先关闭当前客户端的连接socket,再处理其他逻辑,而非先关监听socket。
- 发送数据时未使用字节对象:
self.client.send("OK")会抛出类型错误,导致服务端异常,间接影响连接关闭流程。
修复后的代码
import socket import threading class PLC_Server(threading.Thread): def __init__(self, ip_address="localhost", port=5000): super(PLC_Server, self).__init__() self.ip = ip_address self.port = port self.comm = {"address": self.ip + ":" + str(self.port)} self.buffer_size = 4096 self.client = None def _init_socket(self, listen_num=1): # 创建socket并绑定监听 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((self.ip, int(self.port))) self.sock.listen(listen_num) def run(self): self._init_socket() while True: self.client, address = self.sock.accept() print(f"新客户端连接: {address}") while True: recv_data = self.client.recv(4096) if recv_data == b"": # 检测到客户端关闭连接 print("检测到客户端Socket关闭") # 仅关闭当前客户端的连接socket self.client.close() self.client = None break else: # 发送字节类型的响应 self.client.send(b"OK") if __name__ == '__main__': th1 = PLC_Server() th1.start()
关键修复点
- 移除监听socket的关闭与重新初始化:监听socket应保持运行,持续接收新连接,仅在服务停止时关闭。
- 优先关闭客户端连接socket:检测到客户端断开后,直接关闭
self.client,释放该连接资源,此时TCP协议会自动回复FIN/ACK给客户端。 - 修正发送数据的类型:将
"OK"改为b"OK",符合socket发送字节流的要求。
内容的提问来源于stack exchange,提问作者orilyn
相关产品推荐
相关产品推荐

