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

如何解决以太网传输字典时服务器端的JSON Loads错误?

问题描述

尝试通过以太网从客户端向服务器传输如下结构的字典:

data_transfer_dict={'Target':'', 'Mission':'', 'Optical/IR':'',
 'Arm':'', 'Optical Zoom':0, 'Digital Zoom':0, 'Pitch':00000,
 'Yaw':00000, 'Reset Camera':0, 'Target Selection':0, 'Take Screenshot':0}

尝试了JSON和pickle两种传输方式,其中JSON相关代码如下:

JSON代码

客户端侧

obj1.send_data(json.dumps(data_transfer_dict).encode('utf-8'))
def send_data(self, data):  # 原代码存在拼写错误,应为send_data而非data send
    if self.is_running:
        self.client_socket.send(data)

服务器侧

while True:
    count_bytes=self.client_socket.recv(2048)
    count=json.loads(count_bytes.decode('utf-8'))
    print("Dictionary: ", count)

客户端通过多线程持续发送数据,服务器在持续接收时触发错误:
json.decoder.JSONDecodeError: Extra data: line 1 column 193 (char 192)

问题原因

TCP是流式协议,recv(2048)无法保证每次接收的都是单个完整的JSON数据包:可能一次性收到多个JSON对象拼接的字节流,也可能只收到一个JSON的部分数据。这两种情况都会导致json.loads解析失败,前者就会触发"Extra data"错误。

解决方案

需要给每个JSON数据包添加明确的边界标识,让服务器能准确拆分出每个完整的JSON对象,以下是两种常用实现方式:

方法1:换行符分隔数据包

客户端修改

发送时在JSON字符串末尾添加换行符,作为数据包的结束标记:

obj1.send_data((json.dumps(data_transfer_dict) + '\n').encode('utf-8'))

服务器修改

维护一个数据缓冲区,每次接收数据后追加到缓冲区,再按换行符拆分,只处理完整的JSON内容:

import json

buffer = b''
while True:
    chunk = self.client_socket.recv(2048)
    if not chunk:
        break  # 客户端断开连接
    buffer += chunk
    # 循环拆分缓冲区中的完整JSON行
    while b'\n' in buffer:
        json_bytes, buffer = buffer.split(b'\n', 1)
        try:
            count = json.loads(json_bytes.decode('utf-8'))
            print("Dictionary: ", count)
        except json.JSONDecodeError as e:
            print(f"解析错误: {e}")

方法2:发送数据包长度前缀

客户端修改

先发送JSON数据的字节长度(用固定4字节的大端整数),再发送实际的JSON内容:

json_str = json.dumps(data_transfer_dict)
json_bytes = json_str.encode('utf-8')
# 将数据长度转为4字节大端字节串
length_bytes = len(json_bytes).to_bytes(4, byteorder='big')
# 先发送长度,再发送JSON数据
obj1.send_data(length_bytes + json_bytes)

服务器修改

先接收长度前缀,再根据长度接收完整的JSON数据:

import json

while True:
    # 先接收4字节的长度前缀
    length_bytes = self.client_socket.recv(4)
    if not length_bytes:
        break
    data_length = int.from_bytes(length_bytes, byteorder='big')
    # 接收指定长度的JSON数据
    json_bytes = b''
    while len(json_bytes) < data_length:
        chunk = self.client_socket.recv(data_length - len(json_bytes))
        if not chunk:
            break
        json_bytes += chunk
    if len(json_bytes) == data_length:
        try:
            count = json.loads(json_bytes.decode('utf-8'))
            print("Dictionary: ", count)
        except json.JSONDecodeError as e:
            print(f"解析错误: {e}")
    else:
        print("接收到不完整的数据")

补充说明

  • 换行符分隔法实现简单,适合文本类数据包;json.dumps会自动转义字符串中的换行符,无需额外处理。
  • 长度前缀法更可靠,能精确控制接收字节数,适配各种类型的数据包,避免拆分错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:05:29