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

Python新手求助:流式Socket服务器循环无法接收后续数据包问题

问题分析与修复方案

嘿,我一眼就瞅出你代码里的问题啦——你把sock.accept()放在了while循环的最外层,这就导致程序每次处理完一个数据包后,就又回到等待新连接的状态,完全忽略了同一个客户端的后续数据包!

核心问题拆解

原来的逻辑是:

  1. 进入while循环
  2. 等待新客户端连接(sock.accept())
  3. 接收一次数据
  4. 处理数据
  5. 回到循环开头,再次等待新连接

这就意味着,同一个客户端发的第二个、第三个数据包,程序根本没机会处理,因为它一直卡在accept()那里等新的连接进来。

修复后的代码

我们需要把accept()拿到外层循环,先建立好连接,然后在内部循环里持续从这个连接接收数据,直到客户端断开,再重新等待新连接:

# Configure TAGP listener
import socket
import json

# 假设TAGPListenerPort和client已经初始化
TAGPListenerPort = 12345
# client = ... 你的ThingsBoard客户端初始化代码

ipaddress = ([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
server_name = ipaddress
server_address = (server_name, TAGPListenerPort)
print ('starting TAGP listener on %s port %s' % server_address)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(server_address)
sock.listen(1)
sensor_data = {'tag': 0}

# Listen for TAGP data and forward events to ThingsBoard
try:
    while True:
        print("Waiting for a new connection...")
        # 只在需要新连接时调用accept()
        connection, client_address = sock.accept()
        print(f"Connected from {client_address}")
        try:
            # 内部循环持续接收同一个客户端的数据包
            while True:
                # 用decode处理字节串,避免str(b'xxx')带来的b''前缀问题
                data = connection.recv(1024).decode('utf-8', errors='ignore')
                # 如果recv返回空字符串,说明客户端断开连接
                if not data:
                    print(f"Client {client_address} disconnected")
                    break
                if "EVNTTAG" in data:
                    timestamp = ((data.split())[1])[:17]
                    tag = ((data.split())[1])[17:]
                    sensor_data['tag'] = tag
                    client.publish('v1/devices/me/telemetry', json.dumps(sensor_data), 1)
                    print(f"Received data: {data}")
        finally:
            # 不管连接正常断开还是异常,都关闭连接
            connection.close()
except KeyboardInterrupt:
    # Close socket server (TAGP)
    sock.close()
    # Close client to ThingsBoard
    client.loop_stop()
    client.disconnect()
    print("Server stopped by user")

额外注意事项

  • 数据完整性:recv(1024)只能接收最多1024字节的数据,如果你的数据包超过这个大小,会被截断。可以考虑循环接收直到拿到完整的数据包(比如根据特定分隔符判断)。
  • 字节串处理:原代码里str(connection.recv(1024))会把字节串转成类似b'EVNTTAG...'的字符串,用decode()能得到更干净的文本内容,errors='ignore'可以处理一些非UTF-8的特殊字符。
  • 异常处理:内部循环可以加上except ConnectionResetError之类的异常捕获,避免客户端突然断开导致程序崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:43:11