物联网 基于netty构建mqtt协议规范(轻量级二进制协议)

物联网 基于netty构建mqtt协议规范(轻量级二进制协议)

简述

在物联网、游戏服务器、RPC 等场景中,需要高效的网络通信。 二进制协议相比 JSON/XML 等文本协议,具有更小的体积、更快的解析速度、更低的内存占用等优势。 设计一个简单的二进制协议,并基于 Netty 实现完整的编解码器,深入理解二进制协议的开发流程

源码(netty-sample-03-Binary)

gitee.com/kcnf-iot/io...

协议设计

类 MQTT 风格 的轻量级二进制协议

字段

字节数

描述

魔数 (Magic)

1

固定为 0xAA,用于快速校验和过滤非法连接

消息类型 (Type)

1

1=请求,2=响应,3=心跳

消息ID (MsgId)

4

大端序整数,用于请求-响应关联

数据长度 (Length)

2

无符号短整型(最大 65535),表示后面数据字段的字节数

数据 (Data)

Length

二进制数据(例如 UTF-8 字符串或其他内容)

协议总长度:1+1+4+2+Length = 8+Length 字节

优点

复制代码
魔数帮助快速判断连接是否为合法客户端
长度字段为 2 字节,可表示最大 64KB 的消息体,适合小型物联网设备
消息 ID 使我们可以实现请求-响应的异步模型(如 RPC)

为什么二进制协议更轻量

特性

文本协议 (JSON)

二进制协议

数字编码

"123" 占用3字节

0x7B 占用1字节

布尔值

"true" 占用4字节

1位或1字节

字段名

每次重复发送

靠偏移量隐式约定

解析开销

字符串扫描、递归下降

按位移位、直接取值

示例:{"id":1}

8字节

若协议仅发送 id 数值,只需 4 字节(二进制 int)

server代码

java 复制代码
package com.jysemel.iot.pojo;

import com.jysemel.iot.pojo.coder.BinaryMessageDecoder;
import com.jysemel.iot.pojo.coder.BinaryMessageEncoder;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class BinaryProtocolServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            // 添加二进制解码器和编码器
                            p.addLast(new BinaryMessageDecoder());
                            p.addLast(new BinaryMessageEncoder());
                            p.addLast(new ServerBusinessHandler());
                        }
                    });
            ChannelFuture future = bootstrap.bind(8088).sync();
            System.out.println("二进制协议服务器启动,端口 8088");
            future.channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

client代码

java 复制代码
package com.jysemel.iot.pojo;

import com.jysemel.iot.pojo.coder.BinaryMessageDecoder;
import com.jysemel.iot.pojo.coder.BinaryMessageEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class BinaryProtocolClient {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new BinaryMessageDecoder());
                            p.addLast(new BinaryMessageEncoder());
                            p.addLast(new ClientBusinessHandler());
                        }
                    });
            ChannelFuture future = bootstrap.connect("127.0.0.1", 8088).sync();
            future.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}

验证结果

相关推荐
嘉伟桑1 小时前
Python调用电价API返回JSON示例:分时电价、现货电价和字段解析
后端
武子康1 小时前
Shippy:确定性工具、会话级 Sandbox 与 Live-Data Eval(4 类收敛 + 7 步实现方案 + 6 类评测指标)
前端·人工智能·后端
我叫黑大帅1 小时前
我为什么单一消费者的场景下,要用 Redis List 当消息队列?
redis·后端·面试
AskHarries2 小时前
文件上传系统
后端
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn3 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530143 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908403 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端