本文 MQTT 报文适用于 v3.1.1 和 v5.0 版本,请注意版本


MQTT 报文结构

固定报头 Fix Header

+

可变报头 Variable Header

+

有效载荷 Playload

MQTT报文结构


Fix Header

Fix Header 指每一种 MQTT 报文类型都必包含的报头,最小值为 2 字节(Byte),最大值为 5 字节(Byte)。目前 MQTT(v5.0)有13 种报文,reserved:该数值未有对应报文类型,暂时保留。

报文类型


Byte 1 Bit 7-4 记录该报文类型,对应上图的值。


Remaining Length

Remaining Length 存储可变报头+有效负载的内容大小,不包括存储长度的 Byte!(可变报头/有效负载中有些 Byte 用于存储内容长度)

Remaining Length 长度为 1-4 Byte,根据内容大小变化。Bit 0-6 用于保存长度,Bit 7 (最高位)作为标志位,值为 1 时值未结束,需要在下一 Byte 继续读取。Byte 5 Bit 7 不能为 1,因为最大为 4 Byte,发送错误的报文会通讯失败并收到客户端返回的错误码。

Remaining Length 的存储方式有一点特别,你可以将它理解为 128 进制存储(0111 111)

RemainingLength


例:长度为 16 450

6450 / 128 = 128…66

128 / 128 = 1…0

结果为 1 0 66

Byte 2 = 66,Byte 3 = 0,Byte 4 = 1 (66+0*128+1*128^2)

转化为报文格式


Byte 4 Bit 7 为 0,所以无 Byte 5
若此报文有可变报头,Byte 5 属于可变报头部分


连接

在接下来的表格中,深底色表示 v5.0 特有

在接下来的表格中,深底色表示 v5.0 特有

在接下来的表格中,深底色表示 v5.0 特有


  • 可变报头中的 ‘M’ ‘Q’ ‘T’ ‘T’ 为UTF-8字符
  • 对于 CONNECT 报文,Byte 1 & Byte 3-8 都是固定值
  • 标志位置 0 或置 1 ,1 表确定
  • Keep Alive Timer 占 2 Byte,也就是说最大值 65535 -> 18小时12分15秒。0 为不断开

CONNECT


上图描述转为报文二进制格式,Client ID:6 (自定义的)

由于 Remaining Length 存储可变报头+有效负载的内容大小,并不确定值,所以没有填上

Playload Client ID 部分在 CONNECT 报文是必须包含的,Playload 的其他内容若对应 Flag 没有置1就不需要附上了

由此可以看出 CONNECT 报文最小仅 15 Byte

CONNECT_bin


Client ID:lalala666

CONNECT_bin2


MQTT Broker 收到 CONNECT 会返回一个 CONNACK 报文,确认连接状态

CNNACK


ReasonCode


发布

QoSLevel

发布


发布 QoS 0 消息无需回应,PUBLISH 报文也没有 Message ID 内容

发布qos0回应



发布qos1回应


发布qos1回应_rs



QoS 2 消息发布后,MQTT Broker 回 PUBREC 报文

发布qos2-1回应


PUBREC_rs



收到 MQTT Broker 的 PUBREC 后我们需要回 PUBREL

发布qos2-2回应


PUBREL_rs



最后 MQTT Broker 处理成功回 PUBCMP

发布qos2-3回应


PUBCOMP_rs


订阅

订阅


订阅回应


订阅回应_rs


取消订阅

取消订阅


取消订阅回应


取消订阅回应_rs


心跳

心跳


心跳回应


断开连接

断开


断开_rs