1.MQTT.fx 发起不含遗嘱的连接
连接成功后,查看Wireshark抓包情况如下:
从上图抓包效果,我们可以看出:
(1) MQTT协议是建立在TCP协议的基础上的应用层协议,也就是说MQTT协议也是TCP协议的一种。
(2)MQTT的CONNECT分2步,client先与server建立TCP连接(3次握手),连接成功后,再进行业务层面的连接。
关于TCP的3次握手连接,本系列文章不再赘述,我们重点分析一下MQTT的connect连接流程
1.1 MQTT Client 发送CONNECT报文抓取
Wireshark分析结果如下:
我们对报文内容进行逐个分析:
// 源码
10 3b 00 04 4d 51 54 54 04 c2 00 3c 00 20 65 33 .;..MQTT...<. e3
38 64 39 64 39 61 61 62 62 65 34 31 39 37 39 33 8d9d9aabbe419793
63 65 32 37 32 32 62 35 61 65 35 66 35 36 00 05 ce2722b5ae5f56..
61 64 6d 69 6e 00 06 70 75 62 6c 69 63 admin..public
1.1.1 固定报头
0x10 0x3b
其中:
0x10–对应的是CONNECT
0x3b–剩余长度0x3b个字节。
1.1.2 可变报头
1.1.2.1 协议名
0x00 0x04 0x4d 0x51 0x54 0x54
其中0x00 0x04为协议名称长度–4个字节
0x4d 0x51 0x54 0x54 ,对应的ASCII码为:‘M’, ‘Q’, ‘T’, ‘T’
1.1.2.2 协议等级
0x04 MQTT版本号,04 – v3.1.1
1.1.2.3 连接标志
0xc2
说明后面跟着数据有 User Name、Password,没有遗嘱设置,选择了清理会话方式与服务器连接。
1.1.2.4 保持连接
0x00 0x3c – 对应十进制 为 60 秒。
保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示16位子,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端 必须发送一个PINGREQ 报文。
客户端随时可以发送ping指令,服务器如果发现在KeepAalive时间内没有收到客户端的消息,会自动断开与客户端建立的连接。
1.1.2.5 Client ID
00 20 65 33 38 64 39 64 39 61 61 62 62 65 34 31 39
37 39 33 63 65 32 37 32 32 62 35 61 65 35 66 35 36
其中:
00 20 – Client ID长度为0x20个字节
65 33 38 64 39 64 39 61 61 62 62 65 34 31 39 37 39 33
63 65 32 37 32 32 62 35 61 65 35 66 35 36 – 对应的ASCII码值为:e38d9d9aabbe419793ce2722b5ae5f56
1.1.2.6 User Name
**00 05 61 64 6d 69 6e **
其中:
00 05 – User Name 长度为5个字节
61 64 6d 69 6e – 对应的ASCII码值为: admin
1.1.2.6 Password
00 06 70 75 62 6c 69 63
其中:
00 06 --Password 长度为6个字节
70 75 62 6c 69 63 – 对应的ASCII码值为: public
1.2 MQTT Client 接收到的CONNACK报文抓取
报文源码:
20 02 00 00
1
1.2.1 固定报头
0x20 0x02
其中:
0x20 – 对应的控制包类型为 CONNACK
02 – 剩余字节长度为 2 个字节
1.2.2 可变报头
1.2.2.1 连接确认标志
00
位置:可变报头的第1个字节的第0位
连接确认,具体的内容可以看考MQTT 标准协议.
1.2.2.2 连接返回码
00
位置:可变报头的第2个字节,返回码定义如下:
1.2.3 有效载荷
CONNACK报文没有有效载荷
2 MQTT Client发送包含 遗嘱 的CONNECT
MQTT Client配置遗嘱LWT如下所示:
2.1 含遗嘱参数的CONNECT 抓包
其中CONNECT报文源码如下:
10 2b 00 04 4d 51 54 54 04 e6 00 3c 00 02 63 31 .+..MQTT...<..c1
00 04 57 69 6c 6c 00 06 31 32 33 34 35 36 00 05 ..Will..123456..
61 64 6d 69 6e 00 06 70 75 62 6c 69 63 admin..public
2.1.1 固定报头
0x10 0x2b
其中:
0x10–对应的是CONNECT
0x2b–剩余长度0x2b个字节。
2.1.2 可变报头
2.1.2.1 协议名
0x00 0x04 0x4d 0x51 0x54 0x54
其中0x00 0x04为协议名称长度–4个字节
0x4d 0x51 0x54 0x54 ,对应的ASCII码为:‘M’, ‘Q’, ‘T’, ‘T’
2.1.2.2 协议等级
0x04 MQTT版本号,04 – v3.1.1
2.1.2.3 连接标志
0xe6
说明后面跟着数据有 User Name、Password,可以看到这里will标志都设置为1.
2.1.2.4 保持连接时间
0x00 0x3c – 对应十进制 为 60 秒。
保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示16位子,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端 必须发送一个PINGREQ 报文。
客户端随时可以发送ping指令,服务器如果发现在KeepAalive时间内没有收到客户端的消息,会自动断开与客户端建立的连接。
2.1.2.5 Client ID
00 02 63 31
其中:
00 02 – Client ID长度为2个字节
63 31 – 对应的ASCII码值为: c1
2.1.2.6 Will Topic
00 04 57 69 6c 6c 00 06 31 32 33 34 35 36
00 04 – Will Topic 长度为4个字节
57 69 6c 6c – 对应的ASCII码值为:Will
2.1.2.7 Will Message
00 06 31 32 33 34 35 36 00 05
其中:
00 06 – Will Message 长度为6个字节
31 32 33 34 35 36– 对应的ASCII码值为: 123456
2.1.2.8 User Name
00 05 61 64 6d 69 6e
其中:
00 05 --User Name长度为5个字节
61 64 6d 69 6e – 对应的ASCII码值为: admin
2.1.2.9 Password
00 06 70 75 62 6c 69 63
其中:
00 06 --Password 长度为6个字节
70 75 62 6c 69 63 – 对应的ASCII码值为: public
2.2 含遗嘱参数的 CONNACK 抓包
报文源码:
20 02 00 00
1
2.2.1 固定报头
0x20 0x02
其中:
0x20 – 对应的控制包类型为 CONNACK
02 – 剩余字节长度为 2 个字节
2.2.2 可变报头
2.2.2.1 连接确认标志
00
位置:可变报头的第1个字节的第0位
连接确认,具体的内容可以看考MQTT 标准协议.
2.2.2.2 连接返回码
00
位置:可变报头的第2个字节
2.2.3 有效载荷
CONNACK报文没有有效载荷
小结
MQTT协议的CONNECT/CONNACK还是非常标准的。
如果想要设定遗嘱参数,必须要在进行CONNECT之前就将相关参数设定,才能有效。