MQTT传输带文件信息的JSON数据时解码无法还原原文件问题求助
问题根因
直接对二进制字节数组调用str()方法是错误的:这个操作得到的是字节数组的人类可读表示字符串(比如格式为bytearray(b'\xff\xd8\xff\xe0\x00\x10JFIF...')的普通文本),不是原始二进制数据的编码映射,接收端直接转UTF-8字节当然无法还原原始文件。
正确实现方案
二进制数据要存入JSON,通用标准方案是使用Base64编码:它可以把任意二进制内容转换为由64个可打印ASCII字符组成的字符串,完美兼容JSON的字符串类型要求,解码时可以100%还原原始二进制。
发送端修改代码
import json import base64 file = "pic.jpg" f = open(file, "rb") fileContent = f.read() f.close() fileData = { 'name': file, # 二进制转Base64字符串 'content': base64.b64encode(fileContent).decode('utf-8') } payload = json.dumps(fileData) sender.publish(TOPIC, payload=payload, qos=2, retain=False)
接收端修改代码
import json import base64 def onMessage(client, userdata, msg): print("=> Message Received") fileData = json.loads(msg.payload) # Base64字符串转回原始二进制 raw_content = base64.b64decode(fileData['content']) f = open(fileData['name'], "wb") f.write(raw_content) f.close()
额外优化建议
- Base64编码会让数据体积增加约33%,如果传输大文件,建议使用MQTT 5.0的用户属性携带文件名等元数据,payload直接放原始二进制,不用转Base64也不用封装JSON,传输效率更高。
- 超过MQTT broker消息大小限制的大文件,建议拆分成固定大小的分片传输,接收端按顺序拼接即可。
内容的提问来源于stack exchange,提问作者keen
相关产品推荐
相关产品推荐

