03第三章:【1】_MQTT协议数据包结构

一、MQTT协议数据包结构

在MQTT协议中,一个MQTT数据包由:固定头(Fixed header)、可变头(Variable header)、消息体(payload)三部分构成。MQTT数据包结构如下:

整体MQTT的消息格式如下图所示;

二、MQTT固定头

固定头存在于所有MQTT数据包中,其结构如下:

固定报头的第一个字节分为控制报文的类型(4bit),以及控制报文类型的标志位,控制类型共有14种,其中0与15被系统保留出来,其他的类型具体见:

固定报头的bit0-bit3为标志位,依照报文类型有不同的含义,事实上,除了PUBLISH类型报文以外,其他报文的标志位均为系统保留,PUBLISH报文的第一字节bit3是控制报文的重复分发标志(DUP),bit1-bit2是服务质量等级,bit0是PUBLISH报文的保留标志,用于标识PUBLISH是否保留,当客户端发送一个PUBLISH消息到服务器,如果保留标识位置1,那么服务器应该保留这条消息,当一个新的订阅者订阅这个主题的时候,最后保留的主题消息应被发送到新订阅的用户。

固定报头的第二个字节开始是剩余长度字段,是用于记录剩余报文长度的,表示当前的消息剩余的字节数,包括可变报头和有效载荷区域(如果存在),但剩余长度不包括用于编码剩余长度字段本身的字节数。

剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码,而对于更大的数值则按下面的方式处理:每个字节的低7位用于编码数据长度,最高位(bit7)用于标识剩余长度字段是否有更多的字节,且按照大端模式进行编码,因此每个字节可以编码128个数值和一个延续位,剩余长度字段最大可拥有4个字节。

  • 当剩余长度使用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)。

总的来说,MQTT报文理论上可以发送最大256M的报文,当然,这种情况是非常少的。

固定头存在于所有MQTT数据包中,下面简单分析一下固定头的消息格式:

位置:Byte1 中 bits 7-4 位。

相于一个4位的无符号值,类型、取值及描述如下:

位置:Byte1 中 bits 3-0位。

在不使用标识位的消息类型中,标识位被作为保留位。如果收到无效的标志时,接收端必须关闭网络连接:

(1)DUP:发布消息的副本。用来在保证消息的可靠传输,如果设置为1,则在下面的变长中增加MessageId,并且需要回复确认,以保证消息传输完成,但不能用于检测消息重复发送。

(2)QoS:发布消息的服务质量,即:保证消息传递的次数

Ø00:最多一次,即:

(3)RETAIN: 发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。

三、剩余长度(Remaining Length)

地址:Byte 2。

固定头的第二字节用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为1时,表示长度不足,需要使用二个字节继续保存。例如:计算出后面的大小为0

四、MQTT可变头(Variable header)

MQTT数据包中包含一个可变头,它驻位于固定的头和负载之间。可变头的内容因数据包类型而不同,较常的应用是作为包的标识:

很多类型数据包中都包括一个2字节的数据包标识字段,这些类型的包有:

PUBLISH (QoS > 0)、PUBACK、PUBREC、PUBREL、PUBCOMP、SUBSCRIBE、SUBACK、UNSUBSCRIBE、UNSUBACK。

只有某些报文才拥有可变报头,它在固定报头和有效负载之间,可变报头的内容会根据报文类型的不同而有所不同,但可变报头的报文标识符(Packet Identifier)字段存在于在多个类型的报文里,而有一些报文又没有报文标识符字段,具体见表格,报文标识符结构具体见图:

五、Payload消息体

Payload消息体位MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:

Original: https://www.cnblogs.com/niujifei/p/16341808.html
Author: 格物致知_Tony
Title: 03第三章:【1】_MQTT协议数据包结构

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/539806/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Nginx服务加到systemctl

    当我们编译安装nginx服务后,可以用手执行启动脚本也可以作为服务的形式运行。 添加启动文件:vim /usr/lib/systemd/system/nginx.service c…

    Java 2023年5月30日
    073
  • day03-拉取在线用户功能

    多用户即时通讯系统03 4.编码实现02 4.2功能实现-拉取在线用户 4.2.1思路分析 客户端想要知道在线用户列表,就要向服务器发送请求(Message),因为只有服务器端保持…

    Java 2023年6月15日
    068
  • java学习笔记1(入门级)

    JavaSE (Java标准版) JavaEE(Java企业版) JavaME(Java微型版) 简单性:例如C++支持多继承,多继承比较复杂,而Java不在支持多继承 C++中有…

    Java 2023年6月16日
    079
  • 旅游线路收藏

    判断当前登录用户是否收藏过该线路 当页面加载完成后,发送ajax请求,获取用户是否收藏的标记, 根据标记,展示不同的按钮样式 后台代码 RouteServlet类: /** * 判…

    Java 2023年6月6日
    080
  • 深入MySQL(四):MySQL的SQL查询语句性能优化概述

    关于SQL查询语句的优化,有一些一般的优化步骤,本节就介绍一下通用的优化步骤。 一条查询语句是如何执行的 首先,我们如果要明白一条查询语句所运行的过程,这样我们才能针对过程去进行优…

    Java 2023年6月7日
    074
  • SSM整合

    正常创建一个maven项目,环境是jDK1.8及以上,maven3.8及以上 无论SSM项目、SpringBoot项目还是SpringCloud项目第一件事就是添加相关的依赖。这里…

    Java 2023年6月13日
    093
  • win10找回Ubuntu启动项(非EasyBCD)

    不进入BIOS的情况下找回Ubuntu启动项 最近想对装在电脑上的Ubuntu进行更新,但是之前在BIOS里改了引导系统的文件,导致找不到Ubuntu启动项,EasyBCD程序也不…

    Java 2023年6月7日
    094
  • Kafka到底有多高可靠?(RNG NB)

    在聊Kafka高可靠之前,先在评论区来波RNG NB好不好! 什么叫可靠性? 大家都知道,系统架构有三高: 「高性能、高并发和高可用」,三者的重要性不言而喻。 对于任意系统,想要同…

    Java 2023年6月9日
    089
  • 转摘:Spring、SpringMVC和Springboot的区别

    一、概念 1、Spring Spring是一个开源容器框架,可以接管web层,业务层,dao层,持久层的组件,并且可以配置各种bean,和维护bean与bean之间的关系。其核心就…

    Java 2023年5月30日
    076
  • 线程同步的情景之二

    情景二:数量有限,先到先得 情景简介:与情景一类似,但是这次茅坑的数量不只一个。如果有需求的人数少于茅坑数量,那一切都很和谐。但是人数超过茅坑数量的时候该怎么办?多个人占用一个坑?…

    Java 2023年5月30日
    094
  • Future源码一观-JUC系列

    背景介绍 在程序中,主线程启动一个子线程进行异步计算,主线程是不阻塞继续执行的,这点看起来是非常自然的,都已经选择启动子线程去异步执行了,主线程如果是阻塞的话,那还不如主线程自己去…

    Java 2023年6月13日
    080
  • 分布式文件存储–FastDFS

    上传交互过程 client询问tracker上传到的storage,不需要附加参数; tracker返回一台可用的storage; client直接和storage通讯完成文件上传…

    Java 2023年5月29日
    076
  • 删除链表结点类问题

    删除链表结点 NO1. 删除链表倒数第 k个结点 给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针。要求:空间复杂度 (O(1)),时间复杂度 (O(n)) 如果倒数第…

    Java 2023年6月15日
    098
  • 分布式搜索引擎–02

    1.DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 1.1.DSL查询分类 Elasticsearch提供了基于JSON的DSL(Doma…

    Java 2023年6月9日
    063
  • Cross Site Scripting DOM (XSS) 攻击jQuery append() 的处理方法

    做安全红线使用 工具进行扫描时, 风险。解决该问题有两种办法。 一、原生dom方式 使用JavaScript原生dom替换append方法,原生dom会忽略 Original: h…

    Java 2023年6月13日
    076
  • Java Web:jstl处理字符串

    用法: ${fn:methodName(args….)} 在使用这些函数之前必须在JSP中引入标准函数的声明 <%@ taglib prefix=”fn” uri=”ht…

    Java 2023年5月29日
    080
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球