SpringBoot集成Netty实战:构建高效TCPUDP通信服务端【物联网开发必备】
SpringBoot 集成Netty实现TCP/UDP通信协议【优化版】引言在现代物联网(IoT)应用中设备与服务器之间的实时通信至关重要。Netty作为一个高性能的网络应用框架与SpringBoot的集成可以简化开发过程并提高应用性能。本文将详细介绍如何在SpringBoot中集成Netty实现TCP和UDP通信协议。通讯协议在设计通讯协议时我们考虑了数据的完整性和命令的明确性。以下是我们的协议设计字段名字节数组下标字节长度说明flagbyte[0]-byte[3]4byte固定包头标识使用9527作为固定包头cmdbyte[4]1byte通讯命令operatebyte[5]1byte操作11-发送请求需要回复12-发送请求不需要回复21-回复操作成功22-回复操作失败lengthbyte[6]-byte[7]2byte数据长度(从包头固定标识开始计算总字节数)msgNobyte[8]1byte消息编号(1-255)核心代码3.1 Netty 服务器package com.ljq.demo.springboot.netty.server.init; import com.ljq.demo.springboot.netty.server.handler.UdpRadarNettyServerHandler; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioDatagramChannel; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.net.InetSocketAddress; /** * 初始化雷达UDP服务 */ Slf4j Component public class UdpRadarNettyServer implements ApplicationRunner { Value(${netty.portUdpRadar:9135}) private Integer nettyPort; Resource private UdpRadarNettyServerHandler udpRadarNettyServerHandler; private Channel channel; Override public void run(ApplicationArguments args) throws Exception { this.start(); } /** * 启动服务 */ public void start() throws InterruptedException { EventLoopGroup mainGroup new NioEventLoopGroup(2); EventLoopGroup workGroup new NioEventLoopGroup(8); Bootstrap bootstrap new Bootstrap(); bootstrap.group(mainGroup) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true) .option(ChannelOption.SO_RCVBUF, 1024 * 1024 * 10) .option(ChannelOption.SO_SNDBUF, 1024 * 1024 * 10) .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) .localAddress(new InetSocketAddress(nettyPort)) .handler(new ChannelInitializerNioDatagramChannel() { Override protected void initChannel(NioDatagramChannel nioDatagramChannel) throws Exception { nioDatagramChannel.pipeline() .addLast(workGroup, udpRadarNettyServerHandler); } }); ChannelFuture future bootstrap.bind().sync(); this.channel future.channel(); log.info(---------- [init] UDP Radar netty server start, port:{} ----------, nettyPort); } public Channel getChannel() { return this.channel; } }3.2 Netty 服务端工具类package com.ljq.demo.springboot.netty.server.util; import cn.hutool.core.convert.Convert; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import com.ljq.demo.springboot.netty.server.init.UdpRadarNettyServer; import com.ljq.demo.springboot.netty.server.model.response.UdpRadarHeader; import io.netty.buffer.Unpooled; import io.netty.channel.socket.DatagramPacket; import lombok.extern.slf4j.Slf4j; import java.net.InetSocketAddress; import java.util.Objects; /** * UDP雷达服务端工具类 */ Slf4j public class UdpRadarServerUtil { public static final int HEADER_BYTE_LENGTH 9; public static final int HEADER_DATA_LENGTH 18; public static final int MSG_MAX_LENGTH 1000; public static final String HEADER_FLAG 39353237; private UdpRadarServerUtil() { } /** * 校验服务端接收到的数据是否合法 * * param hexMsg 十六进制消息 * return 是否合法 */ public static boolean validate(String hexMsg) { if (StrUtil.isBlank(hexMsg) || hexMsg.length() HEADER_DATA_LENGTH || hexMsg.length() MSG_MAX_LENGTH || !hexMsg.startsWith(HEADER_FLAG)) { return false; } return true; } /** * 解析请求头 * * param hexMsg 十六进制消息 * return 请求头对象 */ public static UdpRadarHeader parseHeader(String hexMsg) { UdpRadarHeader header new UdpRadarHeader(); header.setFlag(HexUtil.decodeHexStr(hexMsg.substring(0, 8))); header.setCmd(HexUtil.hexToInt(hexMsg.substring(8, 10))); header.setOperate(HexUtil.hexToInt(hexMsg.substring(10, 12))); header.setLength(HexUtil.hexToInt(hexMsg.substring(12, 16))); header.setMsgNo(HexUtil.hexToInt(hexMsg.substring(16, 18))); return header; } /** * 生成发送数据(仅请求头) * * param header 请求头对象 * return 十六进制数据 */ public static String getHexData(UdpRadarHeader header) { StringBuilder dataBuilder new StringBuilder(); dataBuilder.append(HexUtil.encodeHexStr(header.getFlag())); dataBuilder.append(String.format(%02x, header.getCmd())); dataBuilder.append(String.format(%02x, header.getOperate())); dataBuilder.append(String.format(%04x, header.getLength())); dataBuilder.append(String.format(%02x, header.getMsgNo())); return dataBuilder.toString(); } /** * 生成发送数据(包含业务数据) * * param header 请求头对象 * param data 业务数据 * return 十六进制数据 */ public static String getHexData(UdpRadarHeader header, String data) { StringBuilder dataBuilder new StringBuilder(getHexData(header)); if (StrUtil.isNotBlank(data)) { dataBuilder.append(HexUtil.encodeHexStr(data)); } return dataBuilder.toString(); } /** * 向客户端发送数据 * * param clientIp 客户端IP * param clientPort 客户端端口 * param hexMsg 十六进制消息 */ public static void sendData(String clientIp, int clientPort, String hexMsg) { UdpRadarNettyServer udpRadarNettyServer SpringUtil.getBean(UdpRadarNettyServer.class); if (Objects.isNull(udpRadarNettyServer)) { log.warn(UDP Radar Server is not running); return; } DatagramPacket sendPacket new DatagramPacket(Unpooled.copiedBuffer(Convert.hexToBytes(hexMsg)), new InetSocketAddress(clientIp, clientPort)); udpRadarNettyServer.getChannel().writeAndFlush(sendPacket); } /** * 向客户端发送数据 * * param clientId 客户端ID * param clientPort 客户端端口 * param header 请求头对象 * param data 业务数据 */ public static void sendData(String clientId, int clientPort, UdpRadarHeader header, String data) { String hexMsg getHexData(header, data); sendData(clientId, clientPort, hexMsg); } }3.3 Netty 服务处理器package com.ljq.demo.springboot.netty.server.handler; import cn.hutool.core.util.HexUtil; import cn.hutool.core.util.RandomUtil; import com.ljq.demo.springboot.netty.server.model.response.UdpRadarHeader; import com.ljq.demo.springboot.netty.server.util.UdpRadarServerUtil; import io.netty.buffer.ByteBufUtil; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.socket.DatagramPacket; import io.netty.util.concurrent.DefaultThreadFactory; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.net.InetSocketAddress; import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util .concurrent.TimeUnit; /** * UDP雷达服务端处理器 */ Slf4j Component ChannelHandler.Sharable public class UdpRadarNettyServerHandler extends SimpleChannelInboundHandlerDatagramPacket { private final ExecutorService executorService new ThreadPoolExecutor(4, 8, 60, TimeUnit.SECONDS, new LinkedBlockingQueue(10000), new DefaultThreadFactory(UDP-Radar-work-pool), new ThreadPoolExecutor.CallerRunsPolicy()); Override protected void channelRead0(ChannelHandlerContext channelHandlerContext, DatagramPacket packet) throws Exception { String hexMsg ByteBufUtil.hexDump(packet.content()).toUpperCase(); if (!UdpRadarServerUtil.validate(hexMsg)) { log.info(invalid data); return; } InetSocketAddress clientAddress packet.sender(); executorService.execute(() - { UdpRadarHeader header UdpRadarServerUtil.parseHeader(hexMsg); log.info(UDP Radar server receive msg,client: {},cmd:{},operate:{}, clientAddress.getHostString(), header.getCmd(), header.getOperate()); String responseHexMsg demoService(hexMsg); if (Objects.equals(11, header.getOperate())) { UdpRadarServerUtil.sendData(clientAddress.getHostString(), clientAddress.getPort(), responseHexMsg); } }); } /** * 示例业务方法 * * param hexMsg 十六进制消息 * return 响应的十六进制消息 */ private String demoService(String hexMsg) { UdpRadarHeader header UdpRadarServerUtil.parseHeader(hexMsg); UdpRadarHeader responseHeader new UdpRadarHeader(); responseHeader.setCmd(header.getCmd()); responseHeader.setOperate(21); responseHeader.setLength(UdpRadarServerUtil.HEADER_BYTE_LENGTH 5); responseHeader.setMsgNo(header.getMsgNo()); StringBuilder responseHexMsgBuilder new StringBuilder(); responseHexMsgBuilder.append(UdpRadarServerUtil.getHexData(responseHeader)); responseHexMsgBuilder.append(String.format(%02x, RandomUtil.randomInt(0, 128))); responseHexMsgBuilder.append(HexUtil.encodeHexStr(RandomUtil.randomString(4))); return responseHexMsgBuilder.toString(); } }3.4 协议请求头封装类package com.ljq.demo.springboot.netty.server.model.response; import lombok.Data; import java.io.Serializable; /** * UDP雷达请求头参数 */ Data public class UdpRadarHeader implements Serializable { private static final long serialVersionUID 4765355155562316019L; /** * 固定包头标识(4byte) */ private String flag 9527; /** * 命令(1byte) */ private Integer cmd; /** * 操作11-发送请求需要回复12-发送请求不需要回复21-回复操作成功22-回复操作失败(1byte) */ private Integer operate; /** * 数据长度(从包头固定标识开始计算总字节数)(2byte) */ private Integer length; /** * 消息编号(1-255)(1byte) */ private Integer msgNo; }测试4.1 测试工具推荐使用NetAssist网络调试助手来模拟设备发送TCP/UDP指令。下载NetAssist4.2 测试数据原始发送数据{ flag: 9527, cmd: 20, operate: 11, length: 9, msgNo: 85 }编码后的发送数据39353237140b000955后台日志2024-08-20 09:52:41 | INFO | UDP-Radar-work-pool-3-1 | com.ljq.demo.springboot.netty.server.handler.UdpRadarNettyServerHandler 55| UDP Radar server receive msg,client: 192.168.15.32,cmd:20,operate:11扩展阅读和资源链接Netty官方文档SpringBoot官方文档通过本篇文章您能学到什么通过阅读本篇文章您将获得以下知识和技能Netty与SpringBoot集成的理解您将了解如何将Netty框架集成到SpringBoot应用中以及这种集成如何简化物联网通信的开发。TCP/UDP通信协议的实现您将学会如何在Netty中实现TCP和UDP通信协议包括如何配置服务器以及如何处理网络数据。自定义通信协议的设计您将掌握如何设计自定义的通信协议包括数据包的结构和字段定义以及如何确保数据的完整性和命令的明确性。数据编码与解码您将学习如何将数据编码为Hex格式进行传输以及如何将接收到的Hex数据解码回原始格式。网络编程实践您将获得实际的网络编程经验包括如何处理网络连接、数据传输和异常情况。测试工具的使用您将学会如何使用NetAssist这样的网络调试助手来模拟设备发送TCP/UDP指令以及如何进行网络通信的测试。问题解决技巧您将了解一些调试技巧和常见问题的解决方案帮助您在开发过程中快速定位和解决问题。代码阅读与理解通过分析和理解文章中提供的代码示例您将提高代码阅读能力这对于学习和工作中的代码审查都是非常有益的。高性能网络应用开发您将掌握使用Netty开发高性能网络应用的技巧这对于需要处理大量并发网络连接的应用尤为重要。资源链接与扩展学习文章最后提供的资源链接将引导您进行更深入的学习无论是Netty的高级特性还是SpringBoot的最佳实践您都能找到进一步学习的途径。通过本篇文章的学习您不仅能够获得理论知识还能够通过实践加深理解为将来在物联网领域的网络通信开发打下坚实的基础。你掌握了那些或遇到那些问题欢迎评论留言进行讨论

相关新闻

RVC语音合成开源治理:许可证合规检查、贡献者协议签署流程

RVC语音合成开源治理:许可证合规检查、贡献者协议签署流程

RVC语音合成开源治理:许可证合规检查、贡献者协议签署流程 1. 引言:当AI翻唱遇上开源治理 你可能已经体验过RVC(Retrieval-based-Voice-Conversion)的神奇之处——只需要几分钟的训练,就能让AI学会任何人的声音&…

2026/7/5 0:48:36 阅读更多 →
突破Windows安卓应用安装限制:APK Installer无缝跨平台解决方案

突破Windows安卓应用安装限制:APK Installer无缝跨平台解决方案

突破Windows安卓应用安装限制:APK Installer无缝跨平台解决方案 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 在数字化工作环境中,用户经常需…

2026/7/2 23:48:13 阅读更多 →
水墨江南模型STM32嵌入式展示:迷你中式数字画屏项目

水墨江南模型STM32嵌入式展示:迷你中式数字画屏项目

水墨江南模型STM32嵌入式展示:迷你中式数字画屏项目 最近在捣鼓一个挺有意思的小玩意儿,想跟你分享一下。你有没有想过,把那种很有意境的AI生成水墨画,放到一个巴掌大的小屏幕里,让它静静地循环播放,变成一…

2026/7/5 2:21:31 阅读更多 →

最新新闻

5分钟上手:让AI助手成为你的Obsidian智能管家

5分钟上手:让AI助手成为你的Obsidian智能管家

5分钟上手:让AI助手成为你的Obsidian智能管家 【免费下载链接】obsidian-skills Agent skills for Obsidian. Teach your agent to use Obsidian CLI and open formats including Markdown, Bases, JSON Canvas. 项目地址: https://gitcode.com/GitHub_Trending/o…

2026/7/6 18:42:21 阅读更多 →
实战解析:高效构建Suno AI音乐生成API的完整指南

实战解析:高效构建Suno AI音乐生成API的完整指南

实战解析:高效构建Suno AI音乐生成API的完整指南 【免费下载链接】Suno-API Create Music in Seconds with SunoAPI. 项目地址: https://gitcode.com/GitHub_Trending/su/Suno-API Suno-API是一个基于Python和FastAPI的非官方音乐生成API服务,专…

2026/7/6 18:40:19 阅读更多 →
Docker Compose部署docker-http-https-echo最佳实践:完整配置指南

Docker Compose部署docker-http-https-echo最佳实践:完整配置指南

Docker Compose部署docker-http-https-echo最佳实践:完整配置指南 【免费下载链接】docker-http-https-echo Docker image that echoes request data as JSON; listens on HTTP/S, useful for debugging. 项目地址: https://gitcode.com/gh_mirrors/do/docker-htt…

2026/7/6 18:38:17 阅读更多 →
Docker管理新革命:Dockge可视化容器编排完整指南

Docker管理新革命:Dockge可视化容器编排完整指南

Docker管理新革命:Dockge可视化容器编排完整指南 【免费下载链接】dockge A fancy, easy-to-use and reactive self-hosted docker compose.yaml stack-oriented manager 项目地址: https://gitcode.com/GitHub_Trending/do/dockge 厌倦了复杂的Docker命令行…

2026/7/6 18:36:14 阅读更多 →
终极指南:如何用Serial-Studio让串行数据“开口说话“?[特殊字符]

终极指南:如何用Serial-Studio让串行数据“开口说话“?[特殊字符]

终极指南:如何用Serial-Studio让串行数据"开口说话"?🚀 【免费下载链接】Serial-Studio Open-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more. 项目地址: https://gitcode.com/GitHub_Trendi…

2026/7/6 18:36:14 阅读更多 →
【Java毕业设计】基于 SpringBoot 的大学生运动会报名成绩管理系统的设计与实现 基于前后端分离的高校体育赛事组织管理系统(源码+文档+远程调试,全bao定制等)

【Java毕业设计】基于 SpringBoot 的大学生运动会报名成绩管理系统的设计与实现 基于前后端分离的高校体育赛事组织管理系统(源码+文档+远程调试,全bao定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/6 18:34:13 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻