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