获课♥》789it.top/14335/
获取ZY↑↑方打开链接↑↑
MQTT(Message Queuing Telemetry Transport)是一种轻量级的物联网通信协议,其报文长度计算主要涉及**剩余长度(Remaining Length)**字段的编码。剩余长度表示当前报文(可变头 + 负载)的总字节数,采用可变长度的编码方式,最多占用4字节。以下是详细的计算方法:
1. 剩余长度(Remaining Length)的计算规则
剩余长度的编码规则如下:
-
每个字节的最高位(第8位)为标志位:
-
0:表示这是最后一个字节。
-
1:表示后续还有字节。
-
-
剩余长度按低7位优先存储,即数值的低7位在前,高位在后。
-
最终长度 = 所有字节的低7位按权重 (128^0, 128^1, 128^2, \ldots) 计算的总和。
公式
[
\text{剩余长度} = b_0 \times 128^0 + b_1 \times 128^1 + b_2 \times 128^2 + \ldots
]
其中:
-
(b_0, b_1, b_2) 为每个字节的低7位值(去掉最高位的标志位)。
2. 编码示例
示例1:剩余长度 = 300
-
分解数值:
-
300 ÷ 128 = 2 余 44 → 低位字节为
44
,剩余2。 -
2 ÷ 128 = 0 余 2 → 高位字节为
2
。
-
编码:
-
第一个字节:44 + 128(标志位1) →
0xAC
(二进制10101100
)。 -
第二个字节:2(标志位0) →
0x02
(二进制00000010
)。
-
最终编码:
0xAC 0x02
。
示例2:剩余长度 = 20000
-
分解数值:
-
20000 ÷ 128 = 156 余 32 → 低位字节为
32
,剩余156。 -
156 ÷ 128 = 1 余 28 → 第二个字节为
28
,剩余1。 -
1 ÷ 128 = 0 余 1 → 第三个字节为
1
。
-
编码:
-
第一个字节:32 + 128 →
0xA0
(10100000
)。 -
第二个字节:28 + 128 →
0x9C
(10011100
)。 -
第三个字节:1 →
0x01
(00000001
)。
-
最终编码:
0xA0 0x9C 0x01
。
3. 解码示例
示例:编码字节 0xE5 0x31
-
解析每个字节:
-
标志位为0(终止),低7位为
00110001
→ 十进制49
。 -
标志位为1(还有后续字节),低7位为
10100101
→ 十进制101
。 -
第一个字节
0xE5
(二进制11100101
): -
第二个字节
0x31
(二进制00110001
):
-
计算剩余长度:
[
101 \times 128^0 + 49 \times 128^1 = 101 + 6272 = 6373
]
4. 关键注意事项
-
最大支持长度:
-
剩余长度最多占用4字节,最大值为 (2^{28}-1)(即
0xFF, 0xFF, 0xFF, 0x7F
),约 268MB。
-
标志位处理:
-
编码时,除最后一个字节外,所有字节最高位置1。
-
负数问题:
-
MQTT协议规定剩余长度必须为非负整数,无需处理负数。
5. 工具与验证
-
在线编码/解码工具:
-
MQTT Length Calculator
-
-
Python代码示例:
Python
def encode_remaining_length(x): bytes = [] while True: byte = x % 128 x = x // 128 if x > 0: byte |= 0x80 # 设置标志位 bytes.append(byte) if x == 0: break return bytesdef decode_remaining_length(bytes): value = 0 multiplier = 1 for byte in bytes: value += (byte & 0x7F) * multiplier multiplier *= 128 if (byte & 0x80) == 0: break return value
通过上述方法,可以准确计算MQTT报文的剩余长度,确保协议解析的正确性。实际开发中建议结合工具验证编码结果!