IOT-MQTT協議-控制包格式

2.1 MQTT控制包的結構

MQTT協議通過以定義的方式交換一系列MQTT控制數據包來工作。本節介紹這些數據包的格式。

MQTT控制包最多由三部分組成,總是按照以下順序組成,如圖2.1所示 - MQTT控制包的結構

 

圖2.1 - MQTT控制包的結構

固定標頭,存在於所有MQTT控制數據包中

變量頭,存在於某些MQTT控制包中

有效負載,存在於某些MQTT控制數據包中

2.2固定標題

每個MQTT控制包都包含一個固定的頭。圖2.2-固定標題格式說明了固定標題格式。

 

圖2.2 - 固定標題格式

7

6

5

4

3

2

1

0

字節1

MQTT控制包類型

特定於每個MQTT控制數據包類型的標誌

字節2 ...

剩餘長度

 

2.2.1 MQTT控制包類型

位置:字節1,位7-4。

表示爲4位無符號值,值列於表2.1 - 控制數據包類型

 

表2.1 - 控制數據包類型

名稱

流動方向

描述

Reserved 

0

被禁止

保留的

CONNECT

1

客戶端到服務器

客戶端請求連接到服務器

CONNACK

2

服務器到客戶端

連接確認

PUBLISH

3

客戶端到服務器

          或

服務器到客戶端

發佈消息

PUBACK

4

客戶端到服務器

          或

服務器到客戶端

發佈確認

PUBREC

客戶端到服務器

          或

服務器到客戶端

收到發佈(保證交付第1部分)

PUBREL

6

客戶端到服務器

          或

服務器到客戶端

發佈發佈(保證交付第2部分)

PUBCOMP

7

客戶端到服務器

          或

服務器到客戶端

發佈完整(保證交付第3部分)

SUBSCRIBE

8

客戶端到服務器

客戶訂閱請求

SUBACK

9

服務器到客戶端

訂閱確認

UNSUBSCRIBE

10

客戶端到服務器

取消訂閱請求

UNSUBACK

11

服務器到客戶端

取消訂閱確認

PINGREQ

12

客戶端到服務器

PING請求

PINGRESP

13

服務器到客戶端

PING響應

DISCONNECT

14

客戶端到服務器

客戶端優雅斷開並告訴服務器

Reserved

15

被禁止

保留的

         

 

2.2.2 Flags  標誌

固定報頭中字節1的其餘位[3-0]包含特定於每個MQTT控制包類型的標誌,如下面的表2.2-標誌位所列。如果標誌位在表2.2中標記爲“保留” - 標誌位,則保留供將來使用,並且必須設置爲該表 [MQTT-2.2.2-1]中列出的值。如果收到無效標誌,接收方必須關閉網絡連接[MQTT-2.2.2-2] 有關處理錯誤的詳細信息,請參見第4.8 

 

   表2.2 - 標誌位

控制包

固定標頭標誌

第3位

第2位

第1位

位0

CONNECT

保留的

0

0

0

0

CONNACK

保留的

0

0

0

0

PUBLISH

用於MQTT 3.1.1

DUP 1

QoS 2

QoS 2

保留3

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 1        =重複發送發佈控制包

QoS 2        =發佈服務質量

RETAIN 3 = 發佈保留標誌

有關PUBLISH控制包中DUP,QoS和RETAIN標誌的說明,請參見第3.3.1節。

2.2.3 Remaining Length  剩餘長度

位置:從字節2開始。

 

剩餘長度是當前數據包中剩餘的字節數,包括變量頭和有效負載中的數據。剩餘長度不包括用於編碼剩餘長度的字節。

 

剩餘長度使用可變長度編碼方案進行編碼,該方案使用單個字節用於最多127的值。較大的值按如下方式處理。每個字節的最低有效7位對數據進行編碼,最高有效位用於指示表示中有後續字節。因此,每個字節編碼128個值和“連續位”。“剩餘長度”字段中的最大字節數爲四。

 

非規範性評論

例如,64位十進制編碼爲單字節,十進制值64,十六進制0x40。數字321十進制(= 65 + 2 * 128)被編碼爲兩個字節,最不重要的是第一個。第一個字節是65 + 128 = 193.注意,最高位設置爲至少指示一個後續字節。第二個字節是2。

 

非規範性評論

這允許應用程序發送大小高達268,435,455(256 MB)的控制數據包。這個數字在線上的表示是:0xFF,0xFF,0xFF,0x7F。

表2.4顯示了由增加的字節數表示的剩餘長度值。

 

表2.4剩餘長度字段的大小

數字

1

0(0x00)

127(0x7F)

2

128(0x80,0x01)

16 383(0xFF,0x7F)

3

16 384(0x80,0x80,0x01)

2 097 151(0xFF,0xFF,0x7F)

4

2 097 152(0x80,0x80,0x80,0x01)

268 435 455(0xFF,0xFF,0xFF,0x7F)

 

非規範性評論

將非負整數(X)編碼爲可變長度編碼方案的算法如下:

                   

       do 283
               encodedByte = X MOD 128 284
               X = X DIV 128 285
              // if there are more data to encode, set the top bit of this byte 286
              if ( X > 0 ) 287
                  encodedByte = encodedByte OR 128 288
              endif 289
                  'output' encodedByte 290
         while ( X > 0 ) 

 

其中MOD是模運算符(C中的%),DIV 是整數除法(/在C中),OR是按位或(|在C中)。

 

非規範性評論

解碼剩餘長度字段的算法如下:

 multiplier = 1 299
        value = 0 300
        do 301
             encodedByte = 'next byte from stream' 302
             value += (encodedByte AND 127) * multiplier 303
             multiplier *= 128 304
             if (multiplier > 128*128*128) 305
                throw Error(Malformed Remaining Length) 306
        while ((encodedByte AND 128) != 0)

 

其中AND是按位和運算符(& in C)。

 

當此算法終止時,value包含Remaining Length值。

2.3  Variable header 變量頭

某些類型的MQTT控制數據包包含可變標頭組件。它位於固定標頭和有效負載之間。變量頭的內容根據數據包類型而有所不同。變量頭的包標識符字段在幾種包類型中是通用的。

2.3.1包標識符

圖2.3 - 數據包標識符字節

7

6

4

3

2

1

0

字節1

包標識符MSB

字節2

包標識符LSB

 

許多控制分組類型的可變報頭組件包括2字節分組標識符字段。這些控制數據包是PUBLISH(其中QoS> 0),PUBACK,PUBREC,PUBREL,PUBCOMP,SUBSCRIBE,SUBACK,UNSUBSCRIBE,UNSUBACK。

 

SUBSCRIBE,UNSUBSCRIBE和PUBLISH(在QoS> 0的情況下)控制數據包必須包含非零的16位數據包標識符 [MQTT-2.3.1-1]。每次客戶端發送這些類型之一的新數據包時,它必須爲其分配當前未使用的數據包標識符 [MQTT-2.3.1-2]。如果客戶端重新發送特定的控制數據包,那麼它必須在後續重新發送該數據包時使用相同的數據包標識符。客戶端處理完相應的確認數據包後,數據包標識符可以重用。在QoS 1 PUBLISH的情況下,這是相應的PUBACK; 在QoS 2的情況下,它是PUBCOMP。對於SUBSCRIBE或UNSUBSCRIBE,它是相應的SUBACK或UNSUBACK [MQTT-2.3.1-3]。 當服務器發送QoS> 0 [MQTT-2.3.1-4] 的PUBLISH時,相同的條件適用於服務器。

 

如果其QoS值設置爲0,則PUBLISH數據包 不得包含數據包標識符[MQTT-2.3.1-5]

 

PUBACK,PUBREC或PUBREL數據包必須包含與最初發送的PUBLISH數據包相同的數據包標識符 [MQTT-2.3.1-6]。類似地,SUBACK和UNSUBACK必須包含分別在相應的SUBSCRIBE和UNSUBSCRIBE數據包中使用的數據包標識符 [MQTT-2.3.1-7]

 

表2.5 - 包含數據包標識符的控制數據包中列出了需要數據包標識符的控制數據包

表2.5 - 包含數據包標識符的控制數據包

控制包

數據包標識符字段

CONNECT

沒有

CONNACK

沒有

PUBLISH

是(如果QoS> 0)

PUBACK

PUBREC

PUBREL

PUBCOMP

SUBSCRIBE   

SUBACK

UNSUBSCRIBE 

UNSUBACK

PINGREQ

沒有

PINGRESP

沒有

DISCONNECT 

沒有

 

客戶端和服務器彼此獨立地分配數據包標識符。因此,客戶端服務器對可以使用相同的數據包標識符參與併發消息交換。

非規範性評論

客戶端可以發送帶有數據包標識符0x1234的PUBLISH數據包,然後在收到其發送的PUBLISH的PUBACK之前,從其服務器接收帶有數據包標識符0x1234的不同PUBLISH。

 

   客戶端服務器

   PUBLISH Packet Identifier = 0x1234 --- à

   ß -發佈數據包標識符= 0x1234

   PUBACK數據包標識符= 0x1234 --- à

   ß-- PUBACK數據包標識符= 0x1234

2.4 Payload 有效載荷

某些MQTT控制數據包包含有效負載作爲數據包的最後部分,如第3章所述。在PUBLISH數據包的情況下,這是應用程序消息。表2.6 - 包含有效負載的控制數據包列出了需要有效負載的控制數據包。

表2.6 - 包含有效負載的控制數據包

控制包

有效載荷

CONNECT

需要

CONNACK

沒有

PUBLISH

可選的

PUBACK

沒有

PUBREC

沒有

PUBREL

沒有

PUBCOMP

沒有

SUBSCRIBE 

需要

SUBACK

需要

UNSUBSCRIBE 

需要

UNSUBACK

沒有

PINGREQ

沒有

PINGRESP

沒有

DISCONNECT 

沒有

裏面可能有些google翻譯不準的地方請大家多多指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章