文章目錄
- 系列文章目錄
- 前言
- 一、MQTT控制包格式
- 二、固定包頭
- 控制包型別
- 控制包型別標識
- 剩余長度
- 三、可變包頭
- 資料包標識
- 四、載荷
系列文章目錄
MQTT協議詳解 一、MQTT簡介
MQTT協議詳解 二、MQTT控制包格式
前言
本章接詳細介紹MQTT的控制包資料組成,一、MQTT控制包格式
MQTT控制包由一下三個部分組成
| 順序 | 名稱 | 描述 |
|---|---|---|
| 1 | 固定包頭 | 所有MQTT包中 |
| 2 | 可變包頭 | 某些MQTT包中 |
| 3 | 載荷 | 某些MQTT包中 |
二、固定包頭
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte1 | 控制包型別 | 控制包型別標識 | ||||||
| byte2 | 剩余長度 | |||||||
控制包型別
位置:第一個位元組
| 名稱 | 值 | 傳輸方向 | 描述 |
|---|---|---|---|
| Reserved | 0 | 保留 | |
| CONNECT | 1 | 客戶端 --> 服務端 | 客戶端連接請求 |
| CONNACK | 2 | 服務端 --> 客戶端 | 服務器回應客戶端連接請求 |
| PUBLISH | 3 | 客戶端 --> 服務端 OR 服務端 --> 客戶端 | 發布訊息 |
| PUBACK | 4 | 客戶端 --> 服務端 OR 服務端 --> 客戶端 | 發布訊息回應 |
| PUBREC | 5 | 客戶端 --> 服務端 OR 服務端 --> 客戶端 | 發布訊息到達 (交付第一步 ) |
| PUBREL | 6 | 客戶端 --> 服務端 OR 服務端 --> 客戶端 | 發布訊息釋放 (交付第二步) |
| PUBCOMP | 7 | 客戶端 --> 服務端 OR 服務端 --> 客戶端 | 發布訊息完成 (交付第三步) |
| SUBSCRIBE | 8 | 客戶端 --> 服務端 | 客戶端訂閱請求 |
| SUBACK | 9 | 服務端 --> 客戶端 | 服務器回應客戶端訂閱請求 |
| UNSUBSCRIBE | 10 | 客戶端 --> 服務端 | 取消訂閱請求 |
| UNSUBACK | 11 | 服務端 --> 客戶端 | 回應取消訂閱請求 |
| PINGREQ | 12 | 客戶端 --> 服務端 | 心跳請求 |
| PINGRESP | 13 | 服務端 --> 客戶端 | 心跳回應 |
| DISCONNECT | 14 | 客戶端 --> 服務端 | 客戶端斷開連接 |
| Reserved | 15 | 保留 |
控制包型別標識
| 控制包型別 | 固定標志 | bit3 | bit2 | bit1 | bit0 |
|---|---|---|---|---|---|
| CONNECT | 保留 | 0 | 0 | 0 | 0 |
| CONNACK | 保留 | 0 | 0 | 0 | 0 |
| PUBLISH | 根據實際傳輸情況設定 | DUP | QoS | QoS | RETAIN |
| PUBACK | 保留 | 0 | 0 | 0 | 0 |
| PUBREC | 保留 | 0 | 0 | 0 | 0 |
| PUBREL | 保留 | 0 | 0 | 1 | 0 |
| PUBCOMP | 保留 | 0 | 0 | 0 | 0 |
| SUBSCRIBE | 保留 | 0 | 0 | 1 | 0 |
| SUBACK | 保留 | 0 | 0 | 0 | 0 |
| UNSUBSCRIBE | 保留 | 0 | 0 | 1 | 0 |
| UNSUBACK | 保留 | 0 | 0 | 0 | 0 |
| PINGREQ | 保留 | 0 | 0 | 0 | 0 |
| PINGRESP | 保留 | 0 | 0 | 0 | 0 |
| DISCONNECT | 保留 | 0 | 0 | 0 | 0 |
DUP = 重復發送PUBLISH包
QoS = PUBLISH包訊息質量
RETAIN = PUBLISH 保留標識
剩余長度
位置:第二個位元組
剩余長度是指當前包中的剩余位元組,包括可變包頭的資料以及載荷,剩余長度不包含用來編碼剩余長度的位元組,
剩余長度怎么計算呢?說實話,我看了官方的描述很懵逼,但是看代碼后就很清晰了,
| 占用位元組 | 起始數值 | 結束數值 |
|---|---|---|
| 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) |
下面是編碼部分代碼,可以直接放在—》C語言在線編輯器上試一下
#include <stdio.h>
int main(void) {
int encodedByte = 0;
int X = 2097152;//想要進行編碼的長度
int index = 1;
do{
encodedByte = X % 128;
X = X / 128;
if ( X > 0 )
encodedByte = encodedByte | 128;
printf("編碼第%d位元組=%X(HEX)\n",index++,encodedByte);
}while ( X > 0 );
return 0;
}
接下來是解碼部分代碼,也可以在—》C語言在線編輯器上試一下
#include <stdio.h>
int main(void) {
int multiplier = 1;
int buff[4] = {0x80,0x80,0x80,0x01};
int value = 0;
int temp = 0;
int index = 0;
do{
temp = buff[index++];//index先運算,再累加
value += ( temp & 127) * multiplier;
multiplier *= 128;
}while((temp & 128) != 0 );
printf("MQTT控制包長度%d位元組",value);
return 0;
}
三、可變包頭
某些型別的MQTT控制包包含一個可變包頭結構,位于固定包頭和載荷之間,可變包頭的內容取決于包的型別,可變包頭中的包識別符號欄位在大多型別的包中比較常見,
資料包標識
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte1 | 包標識最高有效位 | |||||||
| byte2 | 包標識最低有效位 | |||||||
許多控制資料包型別的可變報頭組件都包含一個2位元組的資料包識別符號欄位,這些控制資料包是PUBLISH(QoS> 0),PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE和UNSUBACK,
SUBSCRIBE,UNSUBSCRIBE和PUBLISH(在QoS> 0的情況下)控制包必須包含一個非零的16位包識別符號 ,每當客戶端發送一個新的資料包(以上四種型別)時,客戶端必須給該資料包分配一個當前未使用的資料包識別符號,如果客戶端重新發送一個特定的控制包,則它必須在該包的后續重新發送中使用相同的包識別符號,在客戶端處理了相應的確認資料包后,資料包識別符號就可以重用,在QoS 1 PUBLISH的情況下,這是對應的PUBACK;在QoS 2的情況下,它是PUBCOMP,對于SUBSCRIBE或UNSUBSCRIBE,它是對應的SUBACK或UNSUBACK , 當服務器發送QoS> 0 的PUBLISH時,同樣的條件也適用于服務器,
如果其QoS值設定為0,則PUBLISH資料包不得包含資料包識別符號,因為Qos=0時,是不會得到回應的,
PUBACK,PUBREC或PUBREL資料包必須包含與最初發送的PUBLISH資料包相同的資料包識別符號,類似地,SUBACK和UNSUBACK必須包含分別在相應的SUBSCRIBE和UNSUBSCRIBE資料包中使用的資料包識別符號,
| 控制包型別 | 是否包含識別符號欄位 |
|---|---|
| CONNECT | 否 |
| CONNACK | 否 |
| PUBLISH | 是(當Qos>0時) |
| PUBACK | 是 |
| PUBREC | 是 |
| PUBREL | 是 |
| PUBCOMP | 是 |
| SUBSCRIBE | 是 |
| SUBACK | 是 |
| UNSUBSCRIBE | 是 |
| UNSUBACK | 是 |
| PINGREQ | 否 |
| PINGRESP | 否 |
| DISCONNECT | 否 |
客戶端和服務端各自獨立分配唯一標識,但是,一對客戶端和服務端交換資料的時候可以使用相同的唯一標識,
四、載荷
有些MQTT控制包的最后一部分會包含載荷,其實負載就是想要傳遞的資料,
| 控制包型別 | 負載 |
|---|---|
| CONNECT | 必須 |
| CONNACK | 無 |
| PUBLISH | 可選(可以空載) |
| PUBACK | 無 |
| PUBREC | 無 |
| PUBREL | 無 |
| PUBCOMP | 無 |
| SUBSCRIBE | 必須 |
| SUBACK | 必須 |
| UNSUBSCRIBE | 必須 |
| UNSUBACK | 無 |
| PINGREQ | 無 |
| PINGRESP | 無 |
| DISCONNECT | 無 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/201057.html
標籤:其他
上一篇:zigbee z-stack 協調器斷電后,重新上電無法恢復網路
下一篇:gin 優雅重啟或停止
