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

Python Socket收到断开消息未关闭致后续代码无法运行求助

问题根因排查
  • 主线程被无限阻塞,后续代码永远无法执行
    你代码中start()函数内部是while True死循环,且server.accept()是阻塞调用,主线程调用start()后会一直卡在监听新连接的逻辑,永远不会执行到start()之后的my_queue.get()、print(msg)两行代码,这是“后续代码无法运行”的核心原因。
  • 连接关闭逻辑存在漏洞,容易出现连接泄漏
    当前逻辑只在收到!DISCONNECT!消息时才会关闭连接,如果客户端出现异常断开(比如网络中断、进程崩溃未发送断开消息),conn.recv()会返回空字节,你的代码只判断了if msg_length:,空值会直接跳过判断逻辑,循环会一直空转,不会主动关闭连接。
修复方案
  1. 将socket服务端监听逻辑放到独立子线程运行,不要阻塞主线程的队列消费逻辑
  2. 补充异常断开的判断逻辑,只要recv返回空字节就直接退出循环关闭连接
  3. 修复日志打印的地址变量错误、替换废弃的API

修复后可正常运行的代码如下:

import threading
import queue
import socket

HEADER = 64
PORT = 6060
SERVER = '0.0.0.0'
ADDR = (SERVER, PORT)
FORMAT = 'utf-8'
DISCONNECT_MESSAGE = "!DISCONNECT!"
my_queue = queue.Queue()
print(SERVER)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 开启端口复用避免重启服务时端口占用报错
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(ADDR)


def handle_client(conn, addr):
    print(f"[NEW CONNECTION] {addr} connected")

    connected = True
    while connected:
        msg_length = conn.recv(HEADER).decode(FORMAT)
        # 补充判断:recv返回空说明客户端已经主动断开,直接退出循环
        if not msg_length:
            connected = False
            break
        msg_length = int(msg_length)
        msg = conn.recv(msg_length).decode(FORMAT)
        if msg == DISCONNECT_MESSAGE:
            connected = False
        else:
            my_queue.put(msg)
        # 打印当前客户端的addr,不是全局服务端ADDR
        print(f"[{addr}] {msg}")
        conn.send("MSG Received".encode(FORMAT))
    conn.close()
    print(f"[CONNECTION CLOSED] {addr} 已断开")

def start():
    server.listen()
    print(f"[LISTENING] Server Is Listening On {SERVER}")
    while True:
        conn, addr = server.accept()
        thread = threading.Thread(target=handle_client, args=(conn, addr))
        thread.start()
        # 替换已废弃的activeCount为Python3标准API active_count,减去监听线程+主线程得到活跃客户端数
        print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 2}")

print("[Starting] Server")
# 把服务端监听逻辑放到守护子线程运行,不阻塞主线程
server_thread = threading.Thread(target=start, daemon=True)
server_thread.start()

# 主线程正常执行队列消费逻辑
while True:
    msg = my_queue.get()
    print(f"[QUEUE RECEIVE] {msg}")

内容的提问来源于stack exchange,提问作者Garberchov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:36:01