MQTT协议学习笔记——报文解析

    xiaoxiao2025-08-02  22

    一、基本概念

    1、标准的MQTT报文结构

    主要分为三部分:固定报头(Fixed Header)、可变报头(Variable Header)、有效载荷(Payload) 其中固定报头为2个字节,一定会存在,其他部分可以没有。

    2、最小报文

    包含两个字段:控制头部、报头长度

    3、控制头部

    包含两个字段:消息类型、标志位

    4、可变报头

    包含四个字段:协议名、协议级别、连接标志、保持连接

    5、连接标志

    包含以下八个字段: 第0位:保留标志位 第1位:清理会话标志 第2位:遗嘱标志 第3,4位:QoS标志 第5位:遗嘱保留Retain标志 第6位:密码 第7位:用户名

    二、Connect

    1、CONNECT(连接服务端)

    含义:客户端请求连接到服务器 (1)、固定报头

        0x10     剩余长度

    (2)、可变报头 依次包含4个字段

        协议名     协议级别     连接标志     保持连接

    Clean Session:清除会话标志 这个标志位用于控制会话状态的生存时间。 如果该位被设置为 0, 则该连接被认为是持久连接, 其具体表现为: 当该客户断开后, 任何订阅的主题和 QoS 被设置为 1 或 2 的信息都会保存, 直到该客户端再次连接上 server 端。 若clean session被设置为 1, 当该客户断开后, 所有的信息都会被移除。客户端和服务端必须丢弃之前的任何会话并开始一个新的会话。

    Will QoS: 发送遗嘱消息的服务等级。

    Will Flag:遗嘱标志 如果被设置为 1,表示如果连接请求被接受了, 遗嘱(Will Message) 消息必须被存储在服务端并且与这个网络连接关联。之后网络连接异常关闭时,服务端必须发布这个遗嘱消息, 除非正常断开。 如果被设置为 0, 连接标志中的 Will QoS 和 Will Retain 字段必须设置为 0, 并且有效载荷中不能包含 Will Topic 和 Will Message 字段。且网络异常断开时, 不能发送遗嘱消息。

    Will Retain: 遗嘱保留标识 如果被写1, 遗嘱消息发布时将会保留且发送给新的订阅消息。

    (3)、有效载荷

    CONNECT的payload字段是根据可变报头的连接标志决定是否存在,如果存在,必须按照以下顺序出现

        客户端标识符(client ID)—必须存在     遗嘱主题(will topic)     遗嘱消息(will msg)     用户名(user name)     密码(password)

    2、CONNACK(确认连接请求)

    含义:连接确认请求,响应CONNECT (1)、固定报头

        0x20     0x02

    (2)、可变报头

        连接确认标志     连接返回码

    连接确认标志: 如果服务端收到清理会话(CleanSession) 标志为 1 的连接,除了将 CONNACK 报文中的返回码设置为 0之外,还必须将 CONNACK 报文中的当前会话设置(Session Present) 标志为 0。如果服务端收到一个 CleanSession 为 0 的连接, 当前会话标志的值取决于服务端是否已经保存了 ClientId对应客户端的会话状态。 如果服务端已经保存了会话状态, 它必须将 CONNACK 报文中的当前会话标志设 置为 1。 如果服务端没有已保存的会话状态, 它必须将 CONNACK 报文中的当前会话设置为 0。 还需要将 CONNACK 报文中的返回码设置为 0 。当前会话标志使服务端和客户端在是否有已存储的会话状态上保持一致。

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

    (3)、有效载荷 无

    3、DISCONNECT(断开连接)

    含义:客户端正常断开连接 (1)、固定报头

        0xE0     0x00

    (2)、可变报头 无

    (3)、有效载荷 无

    4、PINGREQ(心跳请求)

    含义:客户端向服务器发送心跳请求 (1)、固定报头

        0xC0     0x00

    (2)、可变报头 无

    (3)、有效载荷 无

    5、PINGRESP(心跳响应)

    含义:服务端响应服务器发送的心跳请求 (1)、固定报头

        0xD0     0x00

    (2)、可变报头 无

    (3)、有效载荷 无

    三、publish

    1、PUBLISH(发布消息)

    含义:客户端到服务端或者服务端到客户端发布消息控制报文,是双向的。

    一.固定报头 这里写图片描述

    DUP 重发标志 当DUP被设置为0,表示客户端或者服务器是第一次发送这个PUBLISH报文 当DUP被设置为1,表示这可能是一个早期报文的重发 当Qos=0时,DUP 必须为0

    Qos服务质量等级 这里写图片描述

        QoS 0(At most once)“至多一次”     消息发布完全依赖底层 TCP/IP 网络。会发生消息丢失或重复。这一级别可用于如下情况,环境传感器数据,丢失一次读记录无所谓,因为不久后还会有第二次发送。     这里写图片描述

        QoS 1(At least once)“至少一次”     确保消息到达,但消息重复可能会发生。     这里写图片描述

        QoS 2(Exactly once)“只有一次”     这里写图片描述

    **注:**发布者或者订阅者设置的QoS分别是和服务器端异步执行的,即使发布者设置发布消息为QoS2,订阅者也可以通过QoS0或QoS1来订阅该消息(这样就是QoS的降级downgrade)。

    RETAIN保留标志 如果被置为1,服务端必须存储这个topic和它的QoS ,以便它可以被Broker分发给未来的和主题名匹配的订阅者,但是RETAIN=1的Qos=0的PUBLISH的报文发送服务器后,保留消息可能会被服务器选择丢弃保留消息。 保留消息能使新订阅的客户端立即收到最新的状态消息,而不用等待发布者发送下一个更新,也就是topic的保留标志是最后已知的良好值。

    如果要删除保留消息,只需向该topic重新publish数据,RETAIN=TRUE,Payload为空,新订阅者就不会收到保留消息。

    如果客户端发给服务端的 PUBLISH 报文的保留标志位为0, 服务端不能存储这个消息也不能移除或替换任何现存的保留消息。 MQTT Essentials第8部分:保留消息

    二.可变报头

        主题名(Topic name)     报文标识符(Package Identify)- -只有当Qos=1,2时才有

    三.payload 根据用户自定义

    PUBLISH 报文的预期响应

    这里写图片描述

    2、PUBACK(发布确认Qos1)

    含义:发布确认,对 QoS 1 等级的 PUBLISH 报文的响应 一.固定报头

        0x40     0x02

    二.可变报头

        等待确认的 PUBLISH 报文的报文标识符

    二.payload 无

    3、PUBREC(发布收到,step1)

    含义:发布收到,对 QoS 等级 2 的 PUBLISH 报文的响应。它是 QoS 2 等级协议交换的第二个报文。 一.固定报头

        0x50     0x02

    二.可变报头

        等待确认的 PUBLISH 报文的报文标识符

    二.payload 无

    4、PUBREL(发布释放,Qos2,Step2)

    含义:发布释放,报文是对 PUBREC 报文的响应。 它是 QoS 2 等级协议交换的第三个报文。 一.固定报头

        0x62     0x02

    二.可变报头

        等待确认的 PUBREC 报文的报文标识符

    二.payload 无

    5、PUBCOMP(发布完成,Qos2,step3)

    含义:发布完成,是对 PUBREL 报文的响应。 它是 QoS 2 等级协议交换的第四个也是最后一个报文。 一.固定报头

        0x70     0x02

    二.可变报头

        等待确认的 PUBREL 报文的报文标识符

    四、subscribe

    1、SUBSCRIBE(订阅主题)

    含义:客户端向服务器该报文用于订阅一个或者一类topic或者多类tpoic。 一.固定报头

        0x82     剩余长度

    二.可变报头

        报文标识符

    三.payload

        主体过滤器(Tpoic Filter)     服务质量要求(Qos)     …

    注:payload可以是多个Tpoic Filter,但是每个Tpoic Filter后面要有一个Qos

    2、SUBACK(订阅确认)

    含义:服务区对客户端发来SUBSCRIBE报文的响应。

    一.固定报头

        0x90     剩余长度

    二.可变报头

        报文标识符

    三.payload

        和Tpoic Filter对应的实际Qos清单

    3、UNSUBSCRIBE(取消订阅)

    含义:客户端向服务器发送UNSUBSCRIBE,用于取消订阅主题

    一.固定报头

        0xA2     剩余长度

    二.可变报头

        报文标识符

    三.payload

        待取消的Topic

    4、UNSUBACK(取消订阅确认)

    含义:确认收到UNSUBSCRIBE报文 一.固定报头

        0xB0     剩余长度

    二.可变报头

        报文标识符

    三.payload 无

    5、Topic Filter(主题过滤器)

        大小写敏感     可以使用任何UFT-8字符     避免使用$符号开头     通配符 + #(publish时不能使用通配符)

    加号+:单层匹配 井号#:多层匹配,多用于前方一致的匹配

    最新回复(0)