如何解决Python脚本在Ubuntu 20.04运行时出现的JSONDecodeError错误
JSON解码错误排查与解决方案
这个错误的核心原因是传入json.loads的字符串包含超出合法JSON范围的多余内容,且你当前的报错出自TCP数据接收逻辑,和你贴的MQTT消息接收逻辑属于两条不同的链路,优先排查TCP接收相关逻辑:
1 先定位错误来源的真实数据
你现在打印的是MQTT接收的payload,而报错栈指向uiControl.py第83行的getTcpData函数,属于TCP数据接收流程,首先在该函数JSON解析前添加打印,输出完整的原始数据:
def getTcpData(self): # 保留你原有接收TCP数据的代码 print("原始TCP字节内容:", data) decoded_str = data.decode('utf-8') # 用repr打印可以显示不可见的空白、换行、空字符等内容 print("解码后字符串:", repr(decoded_str)) self.taskObj = json.loads(decoded_str)
打印后即可直接看到字符串末尾是否有多余的字符、或者存在多个JSON拼接的情况。
2 高概率诱因:TCP粘包问题
Windows和Linux系统的TCP栈默认缓冲区大小、收包逻辑存在差异,你遇到的跨系统报错大概率是TCP粘包导致:Linux下一次recv操作读取到了连续发送的两个或以上JSON包,拼接后的字符串类似{"code":"101"}{"code":"102"},解析时就会报Extra data错误,Windows因为缓冲区更小每次仅读到单个完整JSON包,所以没有触发问题。
解决方案:
- 标准方案:约定TCP传输协议格式,发送端在发送JSON内容前,先发送4字节的内容长度标记,接收端先读取4字节拿到内容长度,再严格读取对应长度的字节再做解析,从根源避免粘包。
- 轻量方案:约定特殊分隔符,比如每个JSON包末尾追加
\r\n\r\n(保证不会出现在JSON内容中),接收端先按分隔符拆分数据,再对拆分后的单段内容做JSON解析。 - 临时兼容方案:如果不想修改传输逻辑,可以用JSONDecoder的raw_decode方法批量解析拼接的多段JSON:
import json def parse_multi_json(s): decoder = json.JSONDecoder() pos = 0 result_list = [] while pos < len(s): # 跳过空白字符 while pos < len(s) and s[pos].isspace(): pos += 1 if pos >= len(s): break try: obj, pos = decoder.raw_decode(s, pos) result_list.append(obj) except json.JSONDecodeError: break return result_list
调用该函数即可拿到所有拼接的JSON对象,逐个处理即可。
3 其他可能诱因:编码兼容问题
如果JSON内容包含中文或特殊字符,确认发送端编码统一为UTF-8,解码时可添加错误处理参数避免乱码导致解析失败:
decoded_str = data.decode('utf-8', errors='ignore') # 解析前先去除首尾空白字符 self.taskObj = json.loads(decoded_str.strip())
内容的提问来源于stack exchange,提问作者user1543089
相关产品推荐
相关产品推荐

