一、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库:
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency>
构建消息处理器:
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<DatagramPacket> {
@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服务端已经开发完成了。
四、验证
项目启动:
收发消息:
五、源码获取
代码地址:源码仓库文章来源:https://www.toymoban.com/news/detail-729768.html
六、总结
这是在开发工作中用到的UDP编程代码整理而来,如果大家看的过程中有觉得不对的,或者更好的方法,希望大家能够指出来。希望大家多多关注+点赞+收藏 🙏🙏,你们的鼓励是我不断前进的动力💪💪!!!
文章来源地址https://www.toymoban.com/news/detail-729768.html
到了这里,关于《Netty实战篇》快速搭建UDP服务端的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!