0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

网络协议栈:MQTT的报文格式解析

RTThread物联网操作系统 来源:Rice嵌入式开发技术分享 作者:Rice嵌入式开发技术 2021-05-13 14:06 次阅读

在上一篇文章,直接在本地搭建了服务器和客户端,简单的实践了MQTT的用法。而这一篇来解析MQTT的报文格式。MQTT的报文字段很精简。但是解析起来还是有些复杂的。

解析报文最好的工具是采用wireshark抓包,不过我发现,wireshark的2.xxx的版本无法进行回环抓包(即无法抓取127.0.0.1的数据报文)。通过一番度娘,发现新版本的wireshark用Npcap替换WinPcap,Npcap是基于WinPcap 4.1.3开发的,api兼容WinPcap。

030

MQTT报文

MQTT报文格式

MQTT的报文字段主要包含3部分,如下表:

名称 说明
Fixed header(固定报文头) 所有MQTT报文都包含
Variable header(可变报文头) 只有部分MQTT报文包含
Payload(MQTT数据段) 只有部分MQTT报文包含

MQTT固定报文头[Fixed header]

每个MQTT报文都包含一个固定报文头,固定报文头部格式如下:

bit76543210 +-----+-----+-----+-----+-----+-----+-----+-----+-----+ |Byte1|MQTT控制报文类型|指定控制报文类型的标志| +-----+-----------------------------------------------| |Byte2|剩余长度| +-----+-----------------------------------------------| |...|剩余长度| +-----------------------------------------------------|

MQTT控制报文类型

MQTT的控制报文类型在固定报文头的第1个字节的4 ~ 7bit,共4位无符号值。这些值如下表描述:

类型 报文方向 描述
RESERVED 0 禁止 保留
CONNECT 1 客户端到服务端 客户端请求连接服务器
CONNACK 2 服务端到客户端 连接报文确认
PUBLISH 3 双向 发布消息
PUBACK 4 双向 QoS 1消息发布收到确认
PUBREC 5 双向 发布收到(保证交付第一步)
PUBREL 6 双向 发布释放(保证交付第二步)
PUBCOMP 7 双向 QoS 2消息发布完成
SUBSCRIBE 8 客户端到服务端 客户端订阅请求
SUBACK 9 服务端到客户端 订阅请求报文确认
UNSUBSCRIBE 10 客户端到服务端 客户端取消订阅请求
UNSUBACK 11 服务端到客户端 取消订阅请求报文确认
PINGREQ 12 客户端到服务端 心跳请求
PINGRESP 13 服务端到客户端 心跳响应
DISCONNECT 14 客户端到服务端 客户端断开连接
RESERVED 15 禁止 保留

MQTT控制报文标志

MQTT的控制报文标志在固定报文头的第1个字节的4 ~ 7bit,包含每个MQTT报文类型的特定的标志。

注意:如果接收方收到非法的标志,接受者必须关闭网络连接。标志如下表:

其中:

DUP:控制报文的重复分发标志

QoS:PUBLISH报文的服务质量等级

RETAIN:PUBLISH报文的保留标志

类型 报文标志 Bit3 Bit2 Bit1 Bit0
CONNECT Reserved 0 0 0 0
CONNACK Reserved 0 0 0 0
PUBLISH Used in MQTT 3.1.1 DUP QoS QoS RETAIN
PUBACK Reserved 0 0 0 0
PUBREC Reserved 0 0 0 0
PUBREL Reserved 0 0 1 0
PUBCOMP Reserved 0 0 0 0
SUBSCRIBE Reserved 0 0 1 0
SUBACK Reserved 0 0 0 0
UNSUBSCRIBE Reserved 0 0 1 0
UNSUBACK Reserved 0 0 0 0
PINGREQ Reserved 0 0 0 0
PINGRESP Reserved 0 0 0 0
DISCONNECT Reserved 0 0 0 0

MQTT报文剩余长度

剩余长度字段从固定报文头的第2个字节开始,最长可达4个字节,所以剩余长度访问是Byte[2 ~ 5]。

剩余长度表示当前报文剩余部分的字节数,包含可变头部和Payload。

上面的描述,那么怎么确定其长度用几个字节来描述呢?答案:取决于字节的最高位Bit7(默认都是在搞自己在前);如果Bit7为1,那么需要继续计算字节长度,如果Bit7为0,那么不需要继续计算字节长度。

消息长度可以简单理解为128禁止的数据,4位长度最大可以表示:128 * 128 * 128 * 128 Byte = 256MB。

需注意计算规则,低位在前,高位在后,字节最高位Bit7标记是否继续计算消息长度。其消息长度范围如下表:

字节 最小值 最大值
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)

举例:

第一字节最高位是1,需要继续向后计算,去掉标记位(0xC1%128),得到1000001=41

第二字节最高位是1,需要继续向后计算,去掉标记位(0xC2%128),得到1000010=42

第三字节最高位是0,不需要向后计算,其结果就是0x33=51

因为低位在前,高位在后,即消息长度为:41 + 42 * 128 + 51 * 128 * 128=841001Byte = 821KB

0xC1 = 11000001

0xC2 = 11000010

0x33 = 00110011

消息长度是0x60,其二进制是01100000b,字节最高位Bit7位0,所以不需要往后计算,其十进制是96(即消息长度为96个字节)。

消息长度是0xC1, 0xC2, 0x33。分别二进制为:

MQTT可变报文头[Variable header]

在某些MQTT控制报文包含了一个可变报文头部分,它在固定报文头和payload之间,可变报头的内容根据报文类型的不同而不同,可变报头的报文标识符(Packet Identifier)字段存在与多个类型的报文里。可变报头其实就是MQTT开发中使用的Packet ID,通过Packet ID 进行一些操作确认。包含Packet ID的报文类型如下:

类型 包含可变报文头
PUBLISH √(QoS > 0)
PUBACK
PUBREC
PUBREL
PUBCOMP
SUBSCRIBE
SUBACK
UNSUBSCRIBE
UNSUBACK

Packet ID默认是从1开始并自增,如果一个Packet ID被用完后,这个Packet ID可以被重用。对于PUBLISH(QoS 1)来说,如果发送端接收到PUBACK,那么这个Packet ID就用完了。对于PUBLISH(QoS 2),如果接收方收到PUBCOMP,那么这个Packet ID就用完了。对于SUBSCRIBE和UNSUBSCRIBE,Packet ID使用完成的标记是发送方收到了对应的SUBACK和UNSUBACK。

MQTT数据段[Payload]

MQTT中有些报文类型是包含Payload

如PUBLISH的Payload指消息内容。

如CONNECT的Payload指Client Identifier,Will Topic,Will Message,Username,Password等信息

包含Payload的报文类型如下:

类型 包含Payload
CONNECT
PUBLISH 可选
SUBSCRIBE
SUBACK
UNSUBSCRIBE

通过wireshark分析MQTT报文

因为我们的服务器和客户端是在PC上搭建的,所以需要通过wireshark的回环抓包,来分析报文类型CONNECT和CONNACK。

打开wireshark,选择进行回环抓包

使用MQTT.fx创建一个客户端,点击连接,便可以抓到CONNECT和CONNACK的报文。

红色圈子的报文类型CONNECT的内容:

c4fb05c0-b31f-11eb-bf61-12bb97331649.png

内容: 1025 00044d515454 04 c2 003c 0008636c69656e743031 000561646d696e 00083132333435363738

报文类型CONNECT内容分析:

0x10:高四位0001,代表报文类型:CONNECT。

0x25:二进制-0010 0101,Bit7为0,所以剩余长度只有一个字节长,即0x25十进制:37个字节

0x00 0x04 0x4d 0x51 0x54 0x54:其中-0x00,0x04表示协议长度;0x4d 0x51 0x54 0x54对应 "M", "Q", "T", "T"。

0x04:代表MQTT版本号:v3.1.1

0xc2: 次字节含义如下表,该字节描述紧跟数据有 User Name、Password,没有遗嘱设置,选择了清理会话方式与服务器连接。

Bit 7 6 5 4 3 2 1 0
含义 User Name Flag Password Flag Will Retain Flag Will QoS MSB Will QoS LSB Will Flag Clean session Rreserved
1 1 0 0 0 0 1 0


00 3c:对应十进制为60,即保持连接(Keep Alive)60秒,以秒为单位,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端 必须发送一个PINGREQ 报文。客户端随时可以发送ping指令,服务器如果发现在KeepAalive时间内没有收到客户端的消息,会自动断开与客户端建立的连接。

00 08 63 6c 69 65 6e 74 30 31:其中-0x00, 0x08表示clientID的长度8个字节;0x63,0x6c,0x69,0x65,0x6e,0x74,0x30,0x31:代表client01。即是我们在MQTT.fx创建客户端的时候设置clientID。

00 05 61 64 6d 69 6e:其中-0x00,0x05表示User Name的的长度5个字节;0x61,0x64,0x6d,0x69,0x6e:代表User Name为admin,即是我们在MQTT.fx创建客户端的时候设置User Name。

00 08 31 32 33 34 35 36 37 38:其中-0x00,0x08表示User Name的的长度8个字节;0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38:代表Password为12345678,即是我们在MQTT.fx创建客户端的时候设置Password。

红色圈子的报文类型CONNACK的内容:

c5174456-b31f-11eb-bf61-12bb97331649.png

内容: 20 02 00 00

报文类型CONACK内容分析:

20:高四位0010,代表报文类型:CONNACK。

02:二进制-0000 0010,Bit为0,所以剩余长度只有一个字节长,即0x02十进制:2个字节。

00:可变头部的第一个字节的第0位连接确认。

c5331d3e-b31f-11eb-bf61-12bb97331649.png

00:可变头部的第二个字节。

返回码响应 描述
0 0x00连接已接受 连接已被服务器接受
1 0x01连接已拒绝,不支持的协议版本 服务器不支持客户端请求的协议版本
2 0x02连接已拒绝,不合格的客户端ID 客户端ID是正确的UTF-8码,但服务器不允许使用
3 0x03连接已拒绝,服务端不可用 网络连接已建立,但MQTT服务不可用
4 0x04连接已拒绝,无效的用户名或密码 用户名或密码的数据格式无效
5 0x05连接已拒绝,未授权 客户端未被授权连接到此服务器
6-255 Reserved 保留

原文标题:教你动手写网络协议栈-MQTT报文解析6-解析

文章出处:【微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

责任编辑:haq
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 网络
    +关注

    关注

    14

    文章

    7514

    浏览量

    88626
  • 报文数据
    +关注

    关注

    0

    文章

    3

    浏览量

    7622

原文标题:教你动手写网络协议栈-MQTT报文解析6-解析

文章出处:【微信号:RTThread,微信公众号:RTThread物联网操作系统】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    MQTT协议网关的工作原理及功能特性

    在物联网的快速发展中,MQTT协议网关作为连接物联网设备与消息代理服务器的重要桥梁,扮演着不可或缺的角色。MQTT是一种基于发布/订阅模式的轻量级通信协议,特别适用于低带宽、不稳定
    的头像 发表于 09-18 17:00 381次阅读
    <b class='flag-5'>MQTT</b><b class='flag-5'>协议</b>网关的工作原理及功能特性

    Linux网络协议的实现

    网络协议是操作系统核心的一个重要组成部分,负责管理网络通信中的数据包处理。在 Linux 操作系统中,网络
    的头像 发表于 09-10 09:51 257次阅读
    Linux<b class='flag-5'>网络</b><b class='flag-5'>协议</b><b class='flag-5'>栈</b>的实现

    自动售货机MDB协议中文解析(四)通信格式

    自动售货机MDB协议中文解析(四)通信格式
    发表于 09-09 10:45 1次下载

    IEC101、IEC103、IEC104、Modbus报文解析工具

    IEC101\IEC104\IEC103\Modebus报文解析软件,可有效解析上述协议的各种类型报文
    的头像 发表于 09-02 09:56 657次阅读
    IEC101、IEC103、IEC104、Modbus<b class='flag-5'>报文</b><b class='flag-5'>解析</b>工具

    基于MQTT协议云平台的Modbus转MQTT网关

    钡铼Modbus转MQTT网关BL100是一款高性能、高性价比的物联网网关,它支持将Modbus协议(包括Modbus RTU和Modbus TCP)的数据转换为MQTT协议的数据
    的头像 发表于 07-29 17:59 700次阅读
    基于<b class='flag-5'>MQTT</b><b class='flag-5'>协议</b>云平台的Modbus转<b class='flag-5'>MQTT</b>网关

    如何通过北向MQTT自定义报文格式对接到物联网云平台

    不管是公有物联网云平台,还是自建云平台,几乎都会支持MQTT协议,虽然设备和云平台之间都支持MQTT协议,但是双方却无法进行很好的交互上。因为每个公司定义json
    的头像 发表于 06-03 17:11 349次阅读
    如何通过北向<b class='flag-5'>MQTT</b>自定义<b class='flag-5'>报文格式</b>对接到物联网云平台

    modbus报文解析,modbus报文格式详解

    支持点对点和多点通信,可以实现控制器之间的通信。 Modbus报文是Modbus协议中的基本通信单位。Modbus报文包含一个头部和数据部分。头部包含了从站地址、功能码和数据长度等信息,数据部分包含了请求或响应数据。 1. 地址
    的头像 发表于 04-16 15:16 2430次阅读

    CAN报文为什么会发送失败?

    怎么样的。表1是一帧正常标准数据帧的报文组成。表1标准数据帧报文格式组成图1标准数据帧格式CAN总线是一种基于广播的通讯方式,为了保证总线上的每一个正常节点都能正
    的头像 发表于 04-12 08:25 1874次阅读
    CAN<b class='flag-5'>报文</b>为什么会发送失败?

    CAN的报文格式和发送总流程

    在标准格式中,报文的起始位称为帧起始(SOF),然后是由11位标识符和远程发送请求位(RTR)组成的仲裁场。RTR位标明是数据帧还是请求帧,在请求帧中没有数据字节。
    发表于 04-11 10:07 8831次阅读
    CAN的<b class='flag-5'>报文格式</b>和发送总流程

    mqtt协议和tcp协议区别

    带宽和高延迟的网络环境,尤其在物联网环境中表现优秀。而TCP协议是面向连接的、可靠的、基于字节流的传输层通信协议,主要用于互联网和局域网中的数据传输。 2. 连接方式:MQTT
    的头像 发表于 04-01 09:15 1546次阅读

    MQTT协议网关解决方案设计与实施

    MQTT协议网关是一个中间件,负责接收来自不同MQTT客户端的消息,并将这些消息转发到MQTT服务器;同时,也能接收来自MQTT服务器的消息
    的头像 发表于 03-11 14:07 465次阅读

    通信网络协议之UDP协议技术解析

    在通常的网络协议中,TCP/IP协议是一个常见的示例,其中UDP和TCP都是传输层协议。传输
    发表于 02-01 11:00 887次阅读
    通信<b class='flag-5'>网络</b><b class='flag-5'>协议</b><b class='flag-5'>栈</b>之UDP<b class='flag-5'>协议</b>技术<b class='flag-5'>解析</b>

    11种协议报文格式介绍

    用16bit表示所以端口号范围为0~65535,用来标识源主机和目的主机上的进程,用于运输层的多路复用和多路分解。
    的头像 发表于 01-17 10:19 1471次阅读
    11种<b class='flag-5'>协议</b><b class='flag-5'>报文格式</b>介绍

    modbus报文解析,modbus报文格式详解

    支持点对点和多点通信,可以实现控制器之间的通信。 Modbus报文是Modbus协议中的基本通信单位。Modbus报文包含一个头部和数据部分。头部包含了从站地址、功能码和数据长度等信息,数据部分包含了请求或响应数据。   1.
    的头像 发表于 01-09 16:45 5579次阅读

    IPv4报文格式各字段的含义

    Version版本 4Bit :ip报文中,用来表示该协议采用的是那一个版本的ip,相同版本的ip才能进行通信。一般此处的值为4,表示ipv4。
    的头像 发表于 12-13 09:43 2918次阅读
    IPv4<b class='flag-5'>报文格式</b>各字段的含义