1 准备阶段
2 MQTT控制报文格式
2.1 MQTT控制报文结构
- 固定报头,全部控制报文都包含
- 可变报头,部分控制报文包含
- 有效负载,部分控制报文包含
2.2 固定报头
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
MQTT 控制报文的类型 |
用于指定控制报文类型的标志符 |
byte 2 |
剩余长度(可变报头长度 + 有效负载长度) |
(1)MQTT控制报文的类型
CONNECT |
1 |
client -> server |
client 请求链接 server |
CONNACK |
2 |
server -> client |
链接报文确认 |
PINGREQ |
12 |
client -> server |
心跳请求 |
PINGRESP |
13 |
server -> client |
心跳响应 |
DISCONNECT |
14 |
client -> server |
客户端断开链接 |
(2)标识符
CONNECT |
Reserved |
0 |
0 |
0 |
0 |
CONNACK |
Reserved |
0 |
0 |
0 |
0 |
PINGREQ |
Reserved |
0 |
0 |
0 |
0 |
PINGRESP |
Reserved |
0 |
0 |
0 |
0 |
DISCONNECT |
Reserved |
0 |
0 |
0 |
0 |
(3)剩余长度
- 表示当前报文剩余部分的字节数,包括可变报头和负载的数据。
- 它采用了可变长度的编码方法。
- 容许最大长度256M
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) |
2.3 可变报头
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
报文标识符 MSB |
byte 2 |
报文标识符 LSB |
CONNECT |
不须要 |
CONNACK |
不须要 |
PINGREQ |
不须要 |
PINGRESP |
不须要 |
DISCONNECT |
不须要 |
2.4 有效载荷
CONNECT |
须要 |
CONNACK |
不须要 |
PINGREQ |
不须要 |
PINGRESP |
不须要 |
DISCONNECT |
不须要 |
3 MQTT控制报文示例
3.1 CONNECT——链接服务器
(1)WireShark抓包获取报文
MQ Telementry Transport Protocol, Connect Command
# 固定报头(2~5个字节)
Header Flags: 0x10 (Connect Command) # 固定报头,1个字节
0001 .... = Message Type: Connect Command(1) # 报文类型: CONNECT
.... 0000 = Reserved: 0 # 保留
Msg Len: 40 # 剩余长度,0x28,1个字节
# 可变报头,本例10个字节
Protocol Name Length: 4 # 协议长度,0x0004,2个字节
Protocol Name: MQTT # 协议名,MQTT(ASCII:0x4d515454),4个字节
Version: MQTT v3.1.1 (4) # 协议版本,0x04 1个字节
Connect Flags: 0xC2 # 链接标志,1个字节,每一位表明不一样的内容
1... .... = User Name Flag: Set # 用户名
.1.. .... = Password Flag: Set # 密码
..0. .... = Will Retain: Not Set # 遗嘱保留
...0 0... = Qos Level: At most once deliver (Fire and Forget) (0) # Qos
.... .0.. = Will Flag: Not Set # 遗嘱
.... ..1. = Clean Session Flag: Set # 清除会话
.... ...0 = (Reserverd): Not Set # 固定为0
Keep Alive: 60 # 保持链接,2个字节,0x003C
# 有效载荷,本例30个字节
Client ID Length: 14,# 2个字节,0x000e
Client ID: MQTT_FX_client # 14个字节
User Name Length: 5 # 2个字节,0x0005
User Name: hello # 5个字节
Password Length: 5 # 2个字节,0x0005
Password: world # 5个字节
10 28 00 04 4d 51 54 54 04 c2 00 3c 00 0e 4d 51 .(..MQTT...<..MQ
54 54 5f 46 58 5f 43 6c 69 65 6e 74 00 05 68 65 TT_FX_Client..he
6c 6c 6f 00 05 77 6f 72 6c 64 llo..world
(2)链接标志
(3)保持链接时间
- 2个字节表示,以秒为单位,最大值为18小时12分15秒
- 断开状况:
- Client发送PINGREQ,在合理时间内没有回来则关闭到Server的网络链接
- Server在1.5 * 保持链接时间 内没有收到Client的任意控制报文,它将断开Client的网络链接
- 设置为0,表明Server须要由于Client的不活跃而断开链接,可是Server仍然能够在须要的时候关闭链接。
(4)有效载荷
- 客户端标识符(Must):长度 + 标识符(大小写英文或数字),有效载荷的第一个字段,客户端能够提供一个零字节的ClientId,可是Clean Seesion必需为1.
- 遗嘱主体(Option):Will Topic
- 遗嘱消息(Option):Will Message
- 用户名(Option):Username
- 密码(Option)Password
(5)注意
MQTT Server容许Client发送完CONNECT就发送订阅或者发布消息,不过若是验证不经过,Server将关闭链接拒收后面的消息。服务器
3.2 CONNACK——确认链接请求
(1)WireShark抓包获取报文
MQ Telementry Transport Protocol, Connect Command
# 固定报头(2~5个字节)
Header Flags: 0x20 (Connect Ack) # 固定报头,1个字节
0010 .... = Message Type: Connect Ack (2) # 报文类型: CONNACK
.... 0000 = Reserved: 0 # 保留
Msg Len: 2 # 剩余长度,0x02,1个字节
# 可变报头
Acknowledge Flags: 0x00 # 链接确认标志
0000 000. = Reserved: Not Set # 固定为0
.... ...0 = Session Present: Not Set # 当前会话标志
Return Code: Connection Accepted (0) # 链接返回码
(2)当前会话标志
- 若是Server收到一个CleanSession为1的链接,CONNACK报文中的返回码设置为0以外,还须要将CONNACK报文中的当前会话标志设置为0
- 若是Server收到一个CleanSeesion为0的链接,当前会话标志的值取决于Server是否保存了ClientId对应客户端的会话状态。若是保存了,当前会话标志设置为1,不然为0。
(3)链接返回码
0 |
0x00 |
链接已接收 |
1 |
0x01 |
不支持的协议版本 |
2 |
0x02 |
不合格的客户端标识符(UTF-8编码) |
3 |
0x03 |
MQTT服务端不可用(TCP已链接) |
4 |
0x04 |
无效的用户名或密码 |
5 |
0x05 |
未受权此客户端 |
6-255 |
|
保留 |
3.3 PINGREQ——心跳请求
(1)WireShark抓包获取报文
Header Flags: 0xC0 (Ping Request) # 固定报头
1100 .... = Message Type: Ping Request (12)
.... 0000 = Reserved: 0
Msg Len: 0
(2)做用
- 在没有任何其余控制报文发送给Server时,Client告知Server还活着
- 请求Server发送响应确认Server是否活着
- 使用网络以肯定网络链接没有断开
3.4 PINGRESP——心跳响应
(1)WireShark抓包获取报文
Header Flags: 0xD0 (Ping Response) # 固定报头
1101 .... = Message Type: Ping Response(13)
.... 0000 = Reserved: 0
Msg Len: 0
(2)做用
3.5 DISCONNECT——断开链接
(1)WireShark抓包获取报文
Header Flags: 0xe0 (Disconnect) # 固定报头
1110 .... = Message Type: Disconnect (14)
.... 0000 = Reserved: 0
Msg Len: 0
(2)做用
(3)响应
- Client发送DISCONNECT报文后
- 必需关闭网络链接
- 不能经过该链接继续发送任何控制报文
- Server收到DISCONNECT报文后
- 必须丢弃任何与当前链接关联的未发布的遗嘱消息
- 应该关闭网络链接,若是客户端尚未这么作