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報文後
- 必須丟棄任何與當前鏈接關聯的未發佈的遺囑消息
- 應該關閉網絡鏈接,若是客戶端尚未這麼作