You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 16:25:38