# NettyUdpDemo **Repository Path**: arthurliuyuhao/netty-udp-demo ## Basic Information - **Project Name**: NettyUdpDemo - **Description**: Netty实战网络编程源码 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-11-06 - **Last Updated**: 2023-11-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 一、Netty简单介绍   Netty是一个基于NIO的客户、服务端开发框架,使用Netty能够使你快速和简单的开发出一个网络应用,例如实现某种协议的客户、服务端应用。Netty相当于简化和流程化了网络应用的编程过程,例如基于UDP和TCP的socket开发。   “快速而简单”并不意味着生成的应用程序将面临可维护性或性能问题。Netty是经过精心设计的,其经验来自FTP、SMTP、HTTP以及各种二进制和基于文本的传统协议的实现。因此,Netty成功地找到了一种不妥协地实现易于开发、性能、稳定性和灵活性的方法。   其实使用更加简洁的描述的话就是,Netty是对NIO的一次封装,因为JAVA直接使用NIO的话体验感并不是特别好。使用Netty可以实现快速搭建网络通信服务端。 **Features(特点)** 1. Design(设计性) 2. Ease of use(易用性) 3. Performance(高性能) 4. Security(安全) 5. Community(社区性) > 关于Netty的详细介绍会在其他文章与大家见面。 ### 二、关于UDP的内容   UDP(User Datagram Protocol),用户数据报协议。是OSI(Open System Interconnection,开放式系统互联)中的一种协议,提供面向事务简单不可靠传输服务。它具有下面几个特点: **1.客户端与服务端之间是不需要连接的,即无连接性。 2.传输不可靠,不会因为服务端未正常收到数据或解析数据导致让客户端重新发送。 3.传输过程延迟小。 4.传输效率高。** 当然在这里就只是列举了几个相对优秀的特点,这几个特点引发了一部分比较适合的场景: DNS、TFTP、SNMP、屏幕信息显示、设备数据上传等。 ### 三、JAVA基于Netty搭建UDP服务端 项目框架:基于SpringBoot搭建,更适用于实际生产业务使用。 #### 引入maven库: ``` io.netty netty-all 5.0.0.Alpha2 ``` #### 构建消息处理器: ``` package com.example.udpDemo.socket.udp; import cn.hutool.core.util.HexUtil; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.socket.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.net.InetSocketAddress; /** * @author wangdachuan * @version 1.0 * @date 2023/3/14 23:12 **/@Slf4j @Component public class UdpServerHandler extends SimpleChannelInboundHandler { @Override protected void messageReceived(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception { InetSocketAddress sender = datagramPacket.sender(); String ip = sender.getAddress().getHostAddress(); ByteBuf buf = datagramPacket.copy().content(); try { byte[] data = new byte[buf.readableBytes()]; buf.readBytes(data); String dataStr = HexUtil.encodeHexStr(data); log.info("收到IP:{},发送的数据:{}", ip, dataStr); // 下面进行业务代码处理 }catch (Exception e){ e.printStackTrace(); } // TCP返回数据写法 //channelHandlerContext.channel().writeAndFlush("1"); // UDP返回数据写法 channelHandlerContext.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(HexUtil.decodeHex("1")), datagramPacket.sender())); } } ``` SimpleChannelInboundHandler 这个是Netty实现UDP协议需要继承的类。 通过重写messageReceived这个方法来对接收到的消息做业务处理。 UDP返回方法需要注意,跟TCP直接返回也有区别,需要通过DatagramPacket进行封装后返回给客户端。 ``` channelHandlerContext.channel().writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(HexUtil.decodeHex("1")), datagramPacket.sender())); ``` #### 构建Netty启动器 ``` package com.example.udpDemo.socket.udp; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioDatagramChannel; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * @author wangdachuan * @version 1.0 * @date 2023/3/14 23:25 **/@Slf4j @Component public class UdpServer { public void run(){ EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST, true) .handler(new UdpServerHandler()); ChannelFuture channelFuture = b.bind(8081).sync(); log.info("netty构建的UDP服务启动: [port:{}]", 8081); // 等待服务器socket关闭 channelFuture.channel().closeFuture().await(); } catch (Exception e) { log.error("netty构建的UDP服务启动异常-" + e.getMessage()); } finally { group.shutdownGracefully(); } } } ``` [NioEventLoopGroup] 是用来处理I/O操作的多线程事件循环器,Netty提供了许多不同的[EventLoopGroup]的实现用来处理不同传输协议。 **下面就是实现UDP的重点了:** NioDatagramChannel:是一个能收发UDP包的通道,它实现了Netty用来接收UDP包的通道的接口:DatagramChannel 。 其他的参数都是Netty常见参数。 #### 通过项目启动后加载UDP服务 ``` package com.example.udpDemo.socket; import cn.hutool.core.thread.ThreadUtil; import com.example.udpDemo.socket.udp.UdpServer; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; /** * @author wangdachuan * @version 1.0 * @date 2023/3/14 23:31 **/@Slf4j @Component public class StartRunner implements ApplicationRunner { @Resource private UdpServer udpServer; @Override public void run(ApplicationArguments args) throws Exception { log.info("开始启动Netty服务"); // 启动UDP服务 ThreadUtil.execAsync(()->{ udpServer.run(); }); } } ``` 到这里,通过Netty构建UDP服务端已经开发完成了。 ### 四、验证 **项目启动:** ![[udp start.png]] 收发消息: ![[udp message.png]] ### 五、源码获取 代码地址:https://gitee.com/wyc_01/netty-udp-demo.git ### 六、总结 这是在开发工作中用到的UDP编程代码整理而来,如果大家看的过程中有觉得不对的,或者更好的方法,希望大家能够指出来。 `希望大家多多关注+点赞+收藏 🙏🙏,你们的鼓励是我不断前进的动力💪💪!!!`