MQTT解析

Java

java 复制代码
package com.qqbot;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class MqttEntityEncoder {

    public static byte[] encode(MqttEntity entity) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);

        // 1. mdcSn[20]
        writeFixedLengthString(dos, entity.getMdcSn(), 20);

        // 2. length = 54 + msgLen
        int length = 54 + (entity.getMsgBody() == null ? 0 : entity.getMsgBody().length);
        dos.writeInt(Integer.reverseBytes(length)); // 小端写入

        // 3. timeStamp (uint64_t)
        dos.writeLong(Long.reverseBytes(entity.getTimeStamp()));

        // 4. transId[36]
        writeFixedLengthString(dos, entity.getTransId(), 36);

        // 5. msgType (uint16_t)
        dos.writeShort(Short.reverseBytes(entity.getMsgType()));

        // 6. msgLen (uint32_t)
        int msgLen = entity.getMsgBody() == null ? 0 : entity.getMsgBody().length;
        dos.writeInt(Integer.reverseBytes(msgLen));

        // 7. protVer (uint32_t)
        dos.writeInt(Integer.reverseBytes(entity.getProtVer()));

        // 8. msgBody[msgLen]
        if (entity.getMsgBody() != null) {
            dos.write(entity.getMsgBody());
        }

        dos.flush();
        return baos.toByteArray();
    }

    private static void writeFixedLengthString(DataOutputStream dos, String value, int fixedLength) throws IOException {
        byte[] bytes = value != null ? value.getBytes(StandardCharsets.UTF_8) : new byte[0];
        if (bytes.length > fixedLength) {
            dos.write(bytes, 0, fixedLength); // 截断
        } else {
            dos.write(bytes);                 // 写入实际内容
            for (int i = 0; i < fixedLength - bytes.length; i++) {
                dos.writeByte(0);             // 补0
            }
        }
    }

    public static void main(String[] args) throws IOException {
        MqttEntity entity = new MqttEntity();
        entity.setMdcSn("ABC123EFGGGHDDD");
        entity.setTimeStamp(System.currentTimeMillis());
        entity.setTransId("123e4567-e89b-12d3-a456");
        entity.setMsgType((short) 1);
        entity.setProtVer(1);
        entity.setMsgBody("hello mqtt test ddd".getBytes(StandardCharsets.UTF_8));

        byte[] payload = MqttEntityEncoder.encode(entity);
// payload 可直接通过 MQTT 或 TCP 发送
        System.out.println(payload);

    }
}

C++

c 复制代码
#include <iostream>
#include <cstdint>
#include <cstring>

#pragma pack(push, 1)
struct MqttStruct {
    char mdcSn[20];
    uint32_t length;
    uint64_t timeStamp;
    char transId[36];
    uint16_t msgType;
    uint32_t msgLen;
    uint32_t protVer;
    // msgBody follows
};
#pragma pack(pop)

int main() {
    uint8_t data[] = {
        65, 66, 67, 49, 50, 51, 69, 70, 71, 71, 71, 72, 68, 68, 68, 0, 0, 0, 0, 0, // mdcSn
        73, 0, 0, 0,                                                             // length = 73
        33, 227, 216, 122, 152, 1, 0, 0,                                         // timeStamp (小端)
        49, 50, 51, 101, 52, 53, 54, 55, 45, 101, 56, 57, 98, 45, 49, 50, 
        100, 51, 45, 97, 52, 53, 54, 
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                                   // transId 补齐到 36
        1, 0,                                                                    // msgType
        19, 0, 0, 0,                                                             // msgLen = 19
        1, 0, 0, 0,                                                              // protVer
        104, 101, 108, 108, 111, 32, 109, 113, 116, 116, 32, 116, 101, 115, 116, 32, 100, 100, 100
    };

    MqttStruct header{};
    std::memcpy(&header, data, sizeof(MqttStruct));

    std::cout << "mdcSn: " << std::string(header.mdcSn, 20) << std::endl;
    std::cout << "length: " << header.length << std::endl;
    std::cout << "timestamp: " << header.timeStamp << std::endl;
    std::cout << "transId: " << std::string(header.transId, 36) << std::endl;
    std::cout << "msgType: " << header.msgType << std::endl;
    std::cout << "msgLen: " << header.msgLen << std::endl;
    std::cout << "protVer: " << header.protVer << std::endl;

    const char* msgBody = reinterpret_cast<const char*>(data + sizeof(MqttStruct));
    std::cout << "msgBody: " << std::string(msgBody, header.msgLen) << std::endl;

    return 0;
}
相关推荐
m0_5873830044 分钟前
全民健身解决方案软件开发实战:从架构设计到落地指南
java·spring boot·spring·架构·需求分析
白山编程大哥1 小时前
Java OutputStreamWriter 详解:从字符到字节的桥梁
java·开发语言·python
一技安身2 小时前
【信创】Docker‑Compose V2 两种离线部署(独立模式、插件模式)简易教程
java·docker·eureka
七夜zippoe2 小时前
为什么 2026 年每个 Java 团队都该懂 AI Agent
java·开发语言·人工智能
时凌云.2 小时前
【2026最新】JDK 下载安装与环境配置全教程(Windows/Mac/Linux 三平台,零基础友好)
java·linux·macos
Despacito10062 小时前
Java后端性能探查工具速查表
java·开发语言
蓝桉柒73 小时前
下载idea,用idea输入一个程序
java·ide·intellij-idea
蓝桉柒73 小时前
java字面量,变量
java
典典分享指南3 小时前
一品牌多产品线的 GEO 内容矩阵:从策略到落地
java·c#·bash·symfony
用户094248568034 小时前
第3章:OpenJDK从源码到字节码——Class 文件与 javac 管线
java·jvm