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

如何在Python中计算含各组成部分的MQTT数据包大小?

如何正确计算MQTT数据包大小

关于getsizeof计算负载的问题

你的getsizeof(msg.payload)方法不正确。Python的sys.getsizeof()返回的是对象在内存中的总占用大小,包括bytes对象本身的内部结构开销(比如引用计数、类型指针等),而不是负载内容的实际字节长度。

以你给出的负载b'{"0":294.3875741324,"1":292.1924140501}'为例,用len()计算才是它的实际字节数(37字节),而getsizeof()得到的72包含了bytes对象的额外内存开销,完全不能代表负载的真实大小。正确的负载长度计算应该用:

payload_size = len(msg.payload)

MQTT数据包总大小的计算方法

MQTT数据包由4部分组成,总大小是各部分字节数之和:

  • 控制头:固定1字节,包含报文类型(如PUBLISH、SUBSCRIBE)和标志位
  • 剩余长度:1~4字节,采用可变长度编码,表示「可变头+负载」的总字节数
  • 可变长度头:长度取决于报文类型,比如PUBLISH报文的可变头包含主题名(UTF-8编码,前缀2字节表示主题长度+主题内容字节数)、QoS>0时的报文标识符(2字节)
  • 负载:实际消息内容,字节数为len(payload_bytes)

计算步骤示例(以PUBLISH报文为例)

假设你发送的是QoS 0的PUBLISH报文,主题为"device/sensor"(UTF-8编码,长度13字节):

  1. 控制头:1字节
  2. 可变头长度:2(主题长度前缀) +13(主题内容)=15字节
  3. 负载长度:37字节(你的示例负载)
  4. 剩余长度:15+37=52,可变编码后为1字节(0x34)
  5. 总大小:1+1+15+37=54字节

剩余长度的可变编码规则

剩余长度的每个字节只用低7位表示数值,最高位是续位标志(1表示后面还有字节,0表示最后一个字节):

  • 数值≤127:1字节
  • 128~16383:2字节(第一个字节高位置1,低7位存数值的低7位;第二个字节存数值的高7位)
  • 以此类推,最多4字节

更简便的计算方式

如果用Python的MQTT库(如paho-mqtt),可以直接构造报文并获取其字节长度,无需手动计算:

import paho.mqtt.packet as packet

# 构造PUBLISH报文
pub_pkt = packet.PublishPacket()
pub_pkt.topic_name = "device/sensor"
pub_pkt.payload = b'{"0":294.3875741324,"1":292.1924140501}'
pub_pkt.qos = 0  # 根据实际QoS设置

# 打包成字节流并获取总长度
pkt_bytes = pub_pkt.pack()
total_size = len(pkt_bytes)
print(total_size)  # 输出准确的数据包总大小

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 15:27:39