MQTT 5.0 报文解析 01:CONNECT 与 CONNACK

在 MQTT 5.0 报文介绍 中,我们介绍了 MQTT 报文由固定报头、可变报头和有效载荷三个部分组成,以及可变字节整数、属性这类 MQTT 报文中的通用概念。现在,我们将按照实际的用途来进一步介绍各个类型的报文的组成。首先,我们将专注于用于建立 MQTT 连接的报文。

如果我们想要使用 MQTT 进行通信,第一步必然是建立一个 MQTT 连接,而建立 MQTT 连接需要用到两个控制报文,它们分别是 CONNECT 报文与 CONNACK 报文。CONNECT 报文是客户端与服务端建立网络连接后,向服务端发送的第一个控制报文,用来发起连接请求。服务端将返回 CONNACK 报文告知客户端连接结果。

报文示例

我们使用 MQTTX CLI 向 公共 MQTT 服务器 发起一个连接,在这个连接中,我们将协议版本设置 MQTT 5.0,Clean Start 设置为 1,Session Expiry Interval 设置为 300 秒,Keep Alive 设置为 60,用户名和密码分别设置为 admin 和 public,对应的 MQTTX CLI 命令为:

mqttx conn --hostname broker.emqx.io --mqtt-version 5 \  --session-expiry-interval 300 --keepalive 60 --username admin --password public

以下是使用 Wireshark 工具抓取到的 MQTTX CLI 发出的 CONNECT 报文,Linux 环境可以先使用 tcpdump 命令抓取报文,然后再导入至 Wireshark 查看:

10 2f 00 04 4d 51 54 54 05 c2 00 3c 05 11 00 00 01 2c 00 0e 6d 71 74 74 78 5f 30 63 36 36 38 64 30 64 00 05 61 64 6d 69 6e 00 06 70 75 62 6c 69 63

但这是一串不易理解的十六进制字节,除非它们被转换成以下格式:

01connectpacket.png

同样我们也抓取到了公共 MQTT 服务器返回的 CONNACK 报文:

20 13 00 00 10 27 00 10 00 00 25 01 2a 01 29 01 22 ff ff 28 01

在解析这串报文数据之后我们可以看到,CONNACK 报文的 Reason Code 为 0,表示连接成功,后面的多个属性则给出了服务器支持的功能列表,比如支持的最大报文长度,是否支持保留消息等等:

02connackpacket.png

当然,Wireshark 其实也已经为我们列出了报文中各个字段的值,通过下文对 CONNECT 和 CONNACK 报文结构的介绍,再结合 Wireshark 的抓包结果按图索骥,你将很快掌握这两个报文:

03wireshark.png

CONNECT 报文结构

固定报头

CONNECT 报文的固定报头中,位于首字节高 4 位的报文类型字段的值必须为 1(0b0001),首字节中低 4 位则固定全为 0。

所以,CONNECT 报文的第一个字节的值必然为 0x10,我们可以以此来判断某个报文是否为 CONNECT 报文。

MQTT CONNECT 固定报头

可变报头

CONNECT 报文的可变报头按顺序包含以下字段:

MQTT CONNECT 可变报头

  • Protocol Name:这是一个 UTF-8 编码的字符串,用来表示协议名称。在 MQTT 中,UTF-8 编码的字符串的前两个字节统一用于指示后面实际的字符数据的长度。MQTT 3.1.1 和 MQTT 5.0 中协议名称固定为 MQTT,所以对应的以十六进制字节表示的完整内容就是 00 04 4d 51 54 54,其中 4d 51 54 54 就是 MQTT 这个字符串对应的 ASCII 值。最早的 MQTT 3.1 中的协议名称是 MQIsdp,所以它对应的是 00 06 4d 51 49 73 64 70

  • Protocol Version:这是一个单个字节长度的无符号整数,用来表示协议版本。目前只有三个可取值,3 表示 MQTT 3.1,4 表示 MQTT 3.1.1,5 表示 MQTT 5.0。

  • Connect Flags:连接标识,它只有一个字节,但包含了多个用于控制连接行为或指示有效载荷中某些字段是否存在的参数。

    MQTT Connect Flags

    • User Name Flag:用于指示有效载荷是否包含用户名字段。

    • Password Flag:用于指示有效载荷是否包含密码字段。

    • Will Retain:用于指示遗嘱消息是否为保留消息。

    • Will QoS:用于指示遗嘱消息的 QoS。

    • Will Flag:用于指示有效载荷是否包含了遗嘱消息的相关字段。

    • Clean Start:用于指示当前连接是一个新的会话还是一个已存在会话的延续,这决定了服务端将直接新建会话还是尝试复用已存在的会话。

    • Reserved:这是一个保留位,它的值必须为 0。

  • Keep Alive:这是一个双字节长度的无符号整数,用来表示客户端发送两个相邻的控制报文的最大时间间隔。

  • Properties:下表列出了 CONNECT 报文的所有可用属性。

IdentifierProperty NameType
0x11Session Expiry Interval四字节整数
0x21Receive Maximum双字节整数
0x27Maximum Packet Size四字节整数
0x22Topic Alias Maximum双字节整数
0x19Request Response Information单字节
0x17Request Problem Information单字节
0x26User PropertyUTF-8 字符串对
0x15Authentication MethodUTF-8 编码的字符串
0x16Authentication Data二进制数据

有效载荷

CONNECT 报文有效载荷中的字段,除了 Client ID 以外,其他字段都是可选的,它们是否存在取决于可变报头的 Connect Flags 中对应标志位的值。但如果这些存在,就必须按照 Client ID、Will Properties、Will Topic、Will Payload、User Name、Password 的顺序出现。

MQTT 有效载荷

CONNACK 报文结构

固定报文

固定报头中首字节的高 4 位值为 2(0b0010),表示这是一个 CONNACK 报文。

MQTT CONNACK 固定报文

可变报头

CONNACK 报文的可变报头按顺序包含以下字段:

MQTT CONNACK 可变报头

  • Connect Acknowledge Flags:连接确认标志。

    • Reserved (Bit 7 - 1):保留位,必须设置为 0.

    • Session Present (Bit 0):用于指示服务端是否正在使用已存在的会话与客户端恢复通信。仅在客户端在 CONNECT 连接中将 Clean Start 设置为 0 时,Session Present 可能为 1。

  • Reason Code:用于指示连接结果。下表列出了一些在 CONNACK 报文中常见的 Reason Code,完整列表可参阅 MQTT 5.0 Reason Code 速查表。

ValueReason Code NameDescription
0x00Success连接被接受。
0x81Malformed Packet服务端无法按照协议规范正确解析 CONNECT 报文,例如保留位没有按照协议要求设置为 0。
0x82Protocol ErrorCONNECT 报文可以被正确解析,但是内容不符合协议规范,比如 Will Topic 字段的值不是一个合法的 MQTT 主题。
0x84Unsupported Protocol Version服务端不支持客户端所请求的 MQTT 协议版本。
0x85Client Identifier not valid表示 Client ID 是有效的字符串,但是不被服务端接受,比如 Client ID 超出了服务端允许的最大长度。
0x86Bad User Name or Password客户端因为使用了错误的用户名或密码而被拒绝连接。
0x95Packet too largeCONNECT 报文超过了服务端允许的最大长度,可能是因为携带了较大的遗嘱消息。
0x8ABanned表示客户端被禁止登录。例如服务端检测到客户端的异常连接行为,所以将这个客户端的 Client ID 或者 IP 地址加入到了黑名单列表中,又或者是后台管理人员手动封禁了这个客户端,当然以上这些通常需要视服务端的具体实现而定。
  • Properties:下表列出了 CONNACK 报文的所有可用属性。
IdentifierProperty NameType
0x11Session Expiry Interval四字节整数
0x21Receive Maximum双字节整数
0x24Maximum QoS单字节
0x25Retain Available单字节
0x27Maximum Packet Size四字节整数
0x12Assigned Client IdentifierUTF-8 编码的字符串
0x22Topic Alias Maximum双字节整数
0x1FReason StringUTF-8 编码的字符串
0x26User PropertyUTF-8 字符串对
0x28Wildcard Subscription Available单字节
0x29Subscription Identifier Available单字节
0x2AShared Subscription Available单字节
0x13Server Keep Alive双字节整数
0x1AResponse InformationUTF-8 编码的字符串
0x1CServer ReferenceUTF-8 编码的字符串
0x15Authentication MethodUTF-8 编码的字符串
0x16Authentication Data二进制数据

有效载荷

CONNACK 报文不包含有效载荷。

总结

CONNECT 是客户端与服务端的网络连接建立后,客户端发送的第一个 MQTT 报文,CONNACK 作为 CONNECT 的响应报文通过原因码来指示连接结果。

客户端和服务端需要借助 CONNECT 和 CONNACK 报文来完成必要信息的交换,例如客户端使用的协议版本、Client ID、用户名、密码,以及服务端是否存在相应的会话、支持的最大报文长度和最大 QoS 等级等等。

以上就是对 MQTT CONNECT 和 CONNACK 报文的介绍,在后续的文章中,我们还会继续研究 PUBLISH、DISCONNECT 这些报文的结构和组成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/522813.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初识Java中的NIO

1.概述 Java NIO 全称java non-blocking IO ,是指 JDK 提供的新 API。从 JDK1.4 开始,Java 提供了一系列改进的输入/输出新特性,被统称为 NIO(即 New IO),是同步非阻塞的。NIO采用内存映射文件的方式来处理输入输出,NI…

电池UN38.3测试电池模组蓄电池检测报告出具

UN38.3运输报告规定了以下类型的电池: 1. 锂金属电池:包括锂金属氧化物电池(如锂锰电池、锂铁电池、锂钴电池),锂-硫电池等。 2. 锂离子电池:包括锂聚合物电池、锂离子聚合物电池、锂离子含水电池等。 3.…

软考-系统集成项目管理中级-新一代信息技术

本章历年考题分值统计 本章重点常考知识点汇总清单(掌握部分可直接理解记忆) 本章历年考题及答案解析 32、2019 年上半年第 23 题 云计算通过网络提供可动态伸缩的廉价计算能力,(23)不属于云计算的特点。 A.虚拟化 B.高可扩展性 C.按需服务 D.优化本地存储 【参考…

记录一个C语言基础错误——scanf()输入!

今天犯了一个很傻的问题&#xff0c;记录一下。 Lint’Code 题目&#xff1a; 错误代码 #include <stdio.h>int function(int a, int b, int c, int x, int y) {// Write your code hereprintf("In function: %d\n", x y);x - y;return (a * (x y) * (x y…

深圳MES系统服务商

盈致MES系统是一款专业的制造执行系统&#xff0c;专注于为企业提供全面的生产管理解决方案。该系统涵盖了制造数据管理、计划排程管理、生产调度管理、库存管理、质量管理等功能模块&#xff0c;能够帮助企业实现生产过程的数字化、智能化和精益化。 盈致MES系统具有以下特点和…

openharmony launcher 调研笔记(01)数据初始化

最近在看launcher&#xff0c;把自己调研的点做个笔记&#xff0c;持续修改更新中&#xff0c;个人笔记酌情参考。 初始化MainAbility ● common 等 包以 三方库形式 被引入使用 在每个包中的oh-package.json5 文件有配置 { "devDependencies": {}, "n…

宏的使用(C语言详解)

在写一个代码生成可执行文件的过程需要经过编译和链接&#xff0c;编译又要经过三部&#xff1a;预处理&#xff0c;编译&#xff0c;汇编。 #define定义的变量和宏就是在预处理阶段会处理的。 一个简单的宏定义&#xff1a; #include<stdio.h>; #define Max(a,b) a>…

如何利用义乌购API实现用户个性化推荐及商品详情 API 返回值说明

用户个性化推荐 利用义乌购API实现用户个性化推荐是一个涉及多个步骤的过程&#xff0c;主要包括数据收集、用户画像构建、推荐算法选择与实施以及推荐结果的展示与反馈。以下是一个大致的流程和步骤说明&#xff1a; 一、数据收集&#xff1a; 1.用户行为数据&#xff1a;收…

如何理解单片机 pwm 控制的基本原理?

单片机PWM&#xff08;脉宽调制&#xff09;控制的基本原理&#xff0c;简而言之&#xff0c;就是通过改变脉冲信号的宽度&#xff08;占空比&#xff09;来控制模拟电路。这涉及到单片机生成一系列脉冲信号&#xff0c;每个脉冲信号的高电平持续时间和整个周期的比值&#xff…

桌面便签电脑版哪个好?好用便签是哪款

在快节奏的现代生活中&#xff0c;桌面便签软件成为了我们不可或缺的助手。它们轻便、灵活&#xff0c;能够随时记录重要事项&#xff0c;提醒我们按时完成各项任务。面对市面上众多的便签软件&#xff0c;选择一款既实用又好用的便签显得尤为重要。经过深入体验&#xff0c;我…

C++ | Leetcode C++题解之第12题整数转罗马数字

题目&#xff1a; 题解&#xff1a; const string thousands[] {"", "M", "MM", "MMM"}; const string hundreds[] {"", "C", "CC", "CCC", "CD", "D", "DC&qu…

【Angular性能优化】项目8版本加载速度缓慢、白屏时间、首页渲染性能优化方案

前言 随着业务的代码一点点增加,加上Angular的项目本身就比 vue、react 的重一些,随之而来的启动速度,更改文件后编译速度,以及打包速度也会变慢,于是乎想着优化下我们的项目。 本文章主要说的是 : 打包Angular项目的一些配置,性能优化方面的方案打包后,用户进入页面…

vue vue3 手写 动态加载组件

效果展示 一、需求背景&#xff1a; # vue3 项目涉及很多图表加载、表格加载 #考虑手写一个动态加载组件 二、实现思路 通过一个加载状态变量&#xff0c;通过v-if判断&#xff0c;加载状态的变量等于哪一个&#xff0c;动态加载组件内部就显示的哪一块组件。 三、实现效果…

Coursera上托福专项课程03:TOEFL Test-Taking Strategies 学习笔记(完结)

TOEFL Preparation Specialization Specialization Certificate TOEFL Test-Taking Strategies Course Certificate 本文是学习 TOEFL Test-Taking Strategies 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 TOEFL Preparation SpecializationTOEF…

《web应用技术》第二次课后练习

练习目的&#xff1a; 1、form表单值的获取 2、mysql数据库及表的建立&#xff08;参见视频&#xff09; 3、maven项目的建立&#xff08;参见视频&#xff09; 4、使用jdbc进行数据库的增删改查操作。&#xff08;参见源代码&#xff09; 具体如下&#xff1a; 1、继续理…

以Kotti项目为例使用pytest测试项目

在维护和构建大型项目时&#xff0c;单独一个一个手工测试代码已经不适用了&#xff0c;这时候就要用专门的测试框架进行测试。让我们以Kotti项目为例&#xff0c;用pytest这个测试框架进行实践测试吧。 使用python3.10 Ubuntu 系统 准备工作 下载和安装kotti库 pip install…

并查集python实现及题目练习

文章目录 1. 并查集概念1.1 理解并查集&#xff1a;简介与应用场景1.2 Python 实现并查集及优化策略1.3 扁平化栈实现1.4 分析并查集的时间复杂度 2. 情侣牵手3. 相似字符串4. 岛屿数量 如果想了解并查集基础推荐去看左程云大神的算法讲解&#xff0c;非常不错&#xff0c;b站和…

【一】学习TDengine-总结新技术学习的思考

学习TDengine-总结新技术学习的思考 概要 因业务场景需要我们开始接触时序数据库&#xff0c;于是开始根据以往的学习经验着手熟悉这一项新技术&#xff0c;学习也是一种技能&#xff0c;成功的人越容易成功&#xff0c;因为他们掌握了一套成功的方法&#xff0c;这里提到学习经…

【LeetCode热题100】74. 搜索二维矩阵(二分)

一.题目要求 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;…

清明寄哀思,VR云祭扫沉浸式缅怀先烈

只要拿出手机扫一扫&#xff0c;就能通过VR全景&#xff0c;沉浸式走进烈士陵园、纪念场馆&#xff0c;随场景进行同步参观&#xff0c;进行“云祭扫”。这种“云祭扫”活动一经推出就受到了广大群众的追捧&#xff0c;VR全景云祭扫以一种全新、绿色、安全的理念&#xff0c;通…