我最近开始为微控制器编写MQTT库。我一直在关注the specification document。第2.2.3节说明了剩余长度字段(固定报头的一部分)如何对其余数据包中要跟随的字节数进行编码。
它使用一种稍微奇怪的编码方案:
Byte 0 = a mod 128, a /= 128, if a > 0, set top bit and add byte 1
Byte 1 = a mod 128, a /= 128, if a > 0, set top bit... etc
此可变长度编码在此应用程序中似乎很奇怪。您可以使用较少的字节轻松传输相同的数字,尤其是一旦使用此方案获得占用2-4个字节的数字时,尤其如此。 MQTT被设计为易于使用和实现。那么为什么他们选择这种方案呢?
例如,十进制15026222将被编码为0xae 0x90 0x95 0x7
,但是在十六进制中它是0xE5482E
- 3个字节而不是4个字节。计算编码方案并在另一端对其进行解码的开销似乎与认为MQTT在8位微控制器上实现快速且简单的想法相矛盾。
此编码方案有什么好处?为什么使用它?我唯一发现甚至提到任何动机的博客文章都是this one,其中说:
剩余长度字段的编码需要一点额外的位和字节处理,但是好处是大多数消息只需要一个字节,同时保留了发送多达268'435'455字节的更大消息的能力
但这对我来说没有意义。如果您使用整个第一个字节表示0-255而不是0-127,则甚至 more 消息也可能只是一个字节。而且,如果使用正十六进制,则可以表示多达4 294 967 295的数字,而不是仅268 435 455。
有人知道为什么要使用它吗?
答案 0 :(得分:2)
正如您引用的注释所解释的,在“ 大多数消息只需要一个字节”的假设下,换句话说,在大多数情况下,{{1} }只需一个字节即可表示该值。
替代方法是:
使用一个值明确指示a <= 127
需要多少个字节(或位)。这将要求至少2位用于所有消息最多支持a
大小的“ 4字节”。
为a
指定一个固定大小(可能为4个字节),用于所有消息。如果许多(已读:大多数)消息不使用此大小,并且如果需要则不支持更大的值,则效果会较差。