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;
}
相关推荐
君不见,青丝成雪19 分钟前
SpringBoot项目占用内存优化
java·spring boot·后端
一叶飘零_sweeeet31 分钟前
如何避免MyBatis二级缓存中的脏读
java·redis·mybatis
Trust yourself2431 小时前
IDEA控制台乱码(Tomcat)解决方法
java·tomcat·intellij-idea
##学无止境##1 小时前
解锁Java分布式魔法:CAP与BASE的奇幻冒险
java·开发语言·分布式
3Cloudream1 小时前
互联网大厂Java面试深度解析:从基础到微服务云原生的全场景模拟
java·spring boot·redis·elasticsearch·微服务·kafka·电商架构
想买CT5的小曹1 小时前
SpringBoot如何获取系统Controller名称和方法名称
java·spring boot·后端
叫我阿柒啊1 小时前
Java全栈开发工程师的面试实战:从基础到微服务
java·数据库·spring boot·微服务·node.js·vue3·全栈开发
九仞山1 小时前
LangChain4j入门一:LangChain4j简介及核心概念
java·ai·langchain·agents
岁忧2 小时前
(LeetCode 每日一题) 498. 对角线遍历 (矩阵、模拟)
java·c++·算法·leetcode·矩阵·go
做一位快乐的码农2 小时前
基于Spring Boot的旅行足迹分享社区的设计与实现/基于java的在线论坛系统
java·开发语言·spring boot