• 第三章:MQTT协议数据包结构


    一、MQTT协议数据包结构

    在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:

    1. 固定头(Fixed header)。存在于所有MQTT数据包中,表示数据包类型及数据包的分组类标识。
    2. 可变头(Variable header)。存在于部分MQTT数据包中,数据包类型决定了可变头是否存在及其具体内容。
    3. 消息体(Payload)。存在于部分MQTT数据包中,表示客户端收到的具体内容。

    整体MQTT的消息格式如下图所示;

    二、MQTT固定头

    固定头存在于所有MQTT数据包中,其结构如下:

    固定报头的第一个字节分为控制报文的类型(4bit),以及控制报文类型的标志位,控制类型共有14种,其中0与15被系统保留出来,其他的类型具体见:

    固定报头的bit0-bit3为标志位,依照报文类型有不同的含义,事实上,除了PUBLISH类型报文以外,其他报文的标志位均为系统保留,PUBLISH报文的第一字节bit3是控制报文的重复分发标志(DUP),bit1-bit2是服务质量等级,bit0是PUBLISH报文的保留标志,用于标识PUBLISH是否保留,当客户端发送一个PUBLISH消息到服务器,如果保留标识位置1,那么服务器应该保留这条消息,当一个新的订阅者订阅这个主题的时候,最后保留的主题消息应被发送到新订阅的用户。

    固定报头的第二个字节开始是剩余长度字段,是用于记录剩余报文长度的,表示当前的消息剩余的字节数,包括可变报头和有效载荷区域(如果存在),但剩余长度不包括用于编码剩余长度字段本身的字节数。

    剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码,而对于更大的数值则按下面的方式处理:每个字节的低7位用于编码数据长度,最高位(bit7)用于标识剩余长度字段是否有更多的字节,且按照大端模式进行编码,因此每个字节可以编码128个数值和一个延续位,剩余长度字段最大可拥有4个字节。

    • 当剩余长度使用1个字节存储时,其取值范围为0(0x00)~127(0x7f)。

    • 当使用2个字节时,其取值范围为128(0x80,0x01)~16383(0Xff,0x7f)。

    • 当使用3个字节时,其取值范围为16384(0x80,0x80,0x01)~2097151(0xFF,0xFF,0x7F)。

    • 当使用4个字节时,其取值范围为2097152(0x80,0x80,0x80,0x01)~268435455(0xFF,0xFF,0xFF,0x7F)。

    总的来说,MQTT报文理论上可以发送最大256M的报文,当然,这种情况是非常少的。

    固定头存在于所有MQTT数据包中,下面简单分析一下固定头的消息格式:

    1、MQTT消息类型 (message type)

    位置:Byte1 中 bits 7-4 位。

    相于一个4位的无符号值,类型、取值及描述如下:

    2、标识位 (DUP)

    位置:Byte1 中 bits 3-0位。

    在不使用标识位的消息类型中,标识位被作为保留位。如果收到无效的标志时,接收端必须关闭网络连接:

    (1)DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送。

    (2)QoS:发布消息的服务质量,即:保证消息传递的次数

    Ø00:最多一次,即:<=1

    Ø01:至少一次,即:>=1

    Ø10:一次,即:=1

    Ø11:预留

    (3)RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。

    三、剩余长度(Remaining Length)

    地址:Byte 2。

    固定头的第二字节用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为1时,表示长度不足,需要使用二个字节继续保存。例如:计算出后面的大小为0

    四、MQTT可变头(Variable header)

    MQTT数据包中包含一个可变头,它驻位于固定的头和负载之间。可变头的内容因数据包类型而不同,较常的应用是作为包的标识:

    很多类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有:

    PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

    只有某些报文才拥有可变报头,它在固定报头和有效负载之间,可变报头的内容会根据报文类型的不同而有所不同,但可变报头的报文标识符(Packet Identifier)字段存在于在多个类型的报文里,而有一些报文又没有报文标识符字段,具体见表格,报文标识符结构具体见图:

    五、Payload消息体

    Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:

    1. CONNECT,消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。
    2. SUBSCRIBE,消息体内容是一系列的要订阅的主题以及QoS。
    3. SUBACK,消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
    4. UNSUBSCRIBE,消息体内容是要订阅的主题。
  • 相关阅读:
    python2.7打印中文乱码的问题解决
    Tesseract5.0训练字库,提高OCR特殊场景识别率(一)
    git比较重要但是又容易忘记的操作
    ntp局域网时间同步操作
    Flask使用原生sql语句
    Linux的tail命令查看文件
    使用gitlab的webhook进行前端自动部署
    通过queue实现前端的被动接收
    互动interactive与多行输出
    复习
  • 原文地址:https://www.cnblogs.com/niujifei/p/16341808.html
Copyright © 2020-2023  润新知