数据包格式_理解MQTT协议数据包结构
在本教程中,我們將更詳細地介紹MQTT協議,以及MQTT消息或數據包的格式。
我們將研究:
MQTT消息格式。
MQTT消息頭
消息字段和編碼
控制消息編碼示例
介紹
MQTT是基于二進制的協議,控制元素是二進制字節而不是文本字符串。
MQTT使用命令和命令確認格式。
這意味著每個命令都有一個對應的確認。
主題名稱,客戶端ID,用戶名和密碼被編碼為UTF-8字符串。
除了MQTT協議信息(例如客戶端ID等)外,有效負載是二進制數據,內容和格式是特定于應用程序的。
MQTT數據包或消息格式由2字節固定報頭(始終存在)+可變報頭(并非始終存在)+有效負載(并非始終存在)組成。
可能的數據包格式為:
Fixed Header (Control field + Length) – Example CONNACK
Fixed Header (Control field + Length) + Variable Header -Example PUBACK
Fixed Header (Control field + Length)? + Variable Header + payload -Example CONNECT
固定報頭字段由控制字段和可變長度數據包長度字段組成。
數據包長度字段的最小大小為1個字節,用于總長度小于127個字節的消息(不包括控制字段和長度字段)。
最大數據包大小為256MB。小于127字節的小數據包具有1字節的數據包長度字段。
大于127且小于16383的數據包將使用2個字節。等等
注意:只是用7位,第8位用作連續位.
Note:?7 bits are used with the?8th bit?being a?continuation bit.
最小數據包大小只有2個字節,其中包含一個單字節控制字段和一個單字節數據包長度字段。例如,斷開連接消息只有2個字節。
控制字段
8位控制字段是2字節固定報頭的第一個字節。它分為兩個4位字段,包含所有協議命令和響應。
前4個最高有效位是命令或消息類型字段,其他4位用作控制標志。
下表摘自MQTT 3.1.1規范,并顯示了MQTT命令及其相關代碼的示例。
因為它們是8位字節字段中最重要的部分,所以我也以十進制顯示了它們的字節值,就像它們出現在數據包中一樣。
?
控制標志
盡管有16種可能的標志,但實際上只使用其中少部分。
發行消息充分利用了這些標志,如下表所示:
當使用QOS或1或2重新發布消息時使用重復標志
發布消息時使用QOS標志,并指示QOS級別-0,1,2
保留消息標志也用于發布。
?
長度字段(剩余長度)
它的長度在1到4個字節之間。每個字節使用7位作為長度,其中MSB用作連續標志。
剩余長度是長度字段后面的字節數,包括可變長度的頭和有效負載,如下所示:
下面說明了長度為64和321字節的數據包的長度字段
剩余數據包長度64個字節僅需要1個字節:
321個字節的數據包長度需要2個字節的剩余長度字段:
從規范中獲取的下表顯示了數據包大小和數據包長度字段。
?
可變長度頭
如前所述,可變長度頭字段并不總是出現在MQTT消息中。
某些MQTT消息類型或命令要求使用此字段來攜帶其他控制信息。
可變長度報頭字段是相似的,但對于所有消息類型而言都不相同。
MQTT連接和斷開連接消息示例
作為說明,我們現在將查看連接消息的數據包詳細信息。
下面是一個真實的客戶端連接和斷開連接示例,顯示了已發送和已接收數據的實際字節值。
CONNECT控制代碼= 0x10
CONNACK控制碼= 0x20
MQTT數據包=控制+長度+協議名稱+協議級別+連接標志+保持活動+有效負載
(MQTT packet?=control + length + protocol name + Protocol Level +Connect Flags + keep alive +Payload)
注解:
注意連接(0x10)和連接確認(0x20)控制代碼。
注意十六進制0x17或23字節的總長度,其中不包括控制字段和長度字段。長度字段只有1個字節。
您還應該能夠在發送的數據包中看到客戶端ID(python_test)。
當查看實際的數據包字節時,Python會打印十六進制值,除非它可以匹配ASCII字符。在上面的示例中,keep alive字段為x00x3C,但顯示為x00
注解:
客戶端ID字段作為有效內容的第一部分發送,而不是作為頭部的一部分發送。
客戶端ID后跟一個長度字段。
連接標志表明正在請求一個干凈的會話(clean session)。
連接標志是“可變長度”標頭的一部分,用于指示用戶名,密碼的存在與否,以及有效負載中的消息字段。它還包含干凈會話標志和Will QOS。
控制包摘要表
| Control Packet | Variable Header | Payload |
| CONNECT | Required | Required |
| CONNACK | None | None |
| PUBLISH | Required | Optional |
| PUBACK | Required | None |
| PUBREC | Required | None |
| PUBREL | Required | None |
| PUBCOMP | Required | None |
| SUBSCRIBE | Required | Required |
| SUBACK | Required | Required |
| UNSUBSCRIBE | Required | Required |
| UNSUBACK | Required | Required |
| PINGREQ | None | None |
| PINGRESP | None | None |
| DISCONNECT | None | None |
?
Wireshark網絡分析
為了回應讀者有關TCP協議的問題,我創建了這張摘自Wireshark的屏幕截圖。
它顯示了一個MQTT客戶端連接和發布(QOS 1)。您可以清楚地看到總長度為58個字節的ACK數據包。
我們知道ACK數據包是2個字節。
因此,沒有MQTT的TCP數據包約為56個字節。
還有一點需要注意的有趣的事情是直到我完成數據包捕獲之前我都沒有想到的是,每個MQTT命令或響應都將獲得一個TCP ACK,甚至還有一個MQTT ACK。
如果查看屏幕截圖,則MQTT連接可以獲取TCP ACK響應和MQTT Connect ACK響應。
MQTT Connect ACK響應會有一個TCP ACK響應。
參考:MQTT V3.1.1 Specification pdf
http://www.steves-internet-guide.com/mqtt-protocol-messages-overview/
總結
以上是生活随笔為你收集整理的数据包格式_理解MQTT协议数据包结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程判断某个数为素数_【每日编程233期
- 下一篇: lamda list 分组_java8l