Springboot中怎么用Netty开启UDP服务方式
这篇文章主要介绍了Springboot中怎么用Netty开启UDP服务方式,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。
Netty
Netty是一种提供网络编程的工具,是对socket编程的一例优秀的包装,支持TCP、UDP、FTP等协议。我们可以用Netty开发自己的http服务器、udp服务器、FTP服务器,RPC服务器等
Netty大受欢迎的原因:
并发高
Netty支持NIO编程,NIO的持支,可以大大提升并发性能。
传输快
Netty NIO的一个特性是零拷贝,直接在内存中开辟一块,剩去了socket缓冲区,
封装好
接下来写一个简单的udp demo。大体思路:
写一个netty的 基于UDP的Server 用来接受数据
写个一处理类,用于对接受的数据进行处理,然后返回信息
新建一个springboot项目。在pom中引入jar
pom.xml
org.springframework.boot spring-boot-starter 2.1.3.RELEASE org.springframework.boot spring-boot-starter-web io.netty netty-all org.projectlombok lombok true
创建NettyUDPServer
Channel 通道的类型
NioSocketChannel, 代表异步的客户端 TCP Socket 连接.NioServerSocketChannel, 异步的服务器端 TCP Socket 连接.NioDatagramChannel, 异步的 UDP 连接NioSctpChannel, 异步的客户端 Sctp 连接.NioSctpServerChannel, 异步的 Sctp 服务器端连接.OioSocketChannel, 同步的客户端 TCP Socket 连接.OioServerSocketChannel, 同步的服务器端 TCP Socket 连接.OioDatagramChannel, 同步的 UDP 连接OioSctpChannel, 同步的 Sctp 服务器端连接.OioSctpServerChannel, 同步的客户端 TCP Socket 连接.
Bootstrap 是 Netty 提供的一个便利的工厂类,可以通过它来完成 Netty 的客户端或服务器端的 Netty 初始化。
package com.demo.udpdemo.UDPServer;import com.demo.udpdemo.handler.BootNettyUdpSimpleChannelInboundHandler;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;/** * @author */@Slf4jpublic class BootNettyUdpServer { /** * 启动服务 */ public void bind(int port) { log.info("-------------------------------udpServer-------------------------"); //表示服务器连接监听线程组,专门接受 accept 新的客户端client 连接 EventLoopGroup bossLoopGroup = new NioEventLoopGroup(); try { //1,创建netty bootstrap 启动类 Bootstrap serverBootstrap = new Bootstrap(); //2、设置boostrap 的eventLoopGroup线程组 serverBootstrap = serverBootstrap.group(bossLoopGroup); //3、设置NIO UDP连接通道 serverBootstrap = serverBootstrap.channel(NioDatagramChannel.class); //4、设置通道参数 SO_BROADCAST广播形式 serverBootstrap = serverBootstrap.option(ChannelOption.SO_BROADCAST, true); //5、设置处理类 装配流水线 serverBootstrap = serverBootstrap.handler(new BootNettyUdpSimpleChannelInboundHandler()); //6、绑定server,通过调用sync()方法异步阻塞,直到绑定成功 ChannelFuture f = serverBootstrap.bind(port).sync(); log.info(BootNettyUdpServer.class.getName()+" started and listend on "+f.channel().localAddress()); //7、监听通道关闭事件,应用程序会一直等待,直到channel关闭 f.channel().closeFuture().sync(); } catch (Exception e) { // TODO: handle exception } finally { System.out.println("netty udp close!"); //8 关闭EventLoopGroup, bossLoopGroup.shutdownGracefully(); } }}NettyUdpSimpleChannelInboundHandler
package com.demo.udpdemo.handler;import io.netty.buffer.Unpooled;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.channel.socket.DatagramPacket;import io.netty.util.CharsetUtil;import lombok.extern.slf4j.Slf4j;/** * @author */@Slf4jpublic class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler{ @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { try { String strdata = msg.content().toString(CharsetUtil.UTF_8); //打印收到的消息 log.info("---------------------receive data--------------------------"); log.info(strdata); log.info("---------------------receive data--------------------------"); //收到udp消息后,可通过此方式原路返回的方式返回消息,例如返回时间戳 ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("ok", CharsetUtil.UTF_8), msg.sender())); } catch (Exception e) { } }}
修改启动类,启动执行UDPServer.bind方法,启动udpServer
@SpringBootApplication@EnableAsyncpublic class UdpDemoApplication implements CommandLineRunner { public static void main(String[] args) { SpringApplication app = new SpringApplication(UdpDemoApplication.class); app.run(args); } @Async @Override public void run(String... args){ new BootNettyUdpServer().bind(51000); }}test
在test类下面,新建一个test方法
sendUdpRequestTest
//定义客户端ip private static final String SERVER_HOSTNAME = "127.0.0.1"; // 服务器端口 private static final int SERVER_PORT = 51000; // 本地发送端口 private static final int LOCAL_PORT = 8888; @Test public void sendUdpRequestTest() { try { // 1,创建udp服务。通过DatagramSocket对象。 DatagramSocket socket = new DatagramSocket(LOCAL_PORT); // 2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress // address, int port) byte[] buf = "hello".getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName(SERVER_HOSTNAME), SERVER_PORT); // 3,通过socket服务,将已有的数据包发送出去。通过send方法。 socket.send(dp); // 4,关闭资源。 socket.close(); } catch (IOException e) { e.printStackTrace(); } }结果
2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : 你好,世界
2021-09-03 13:14:47.912 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : 你好,世界
2021-09-03 13:16:11.748 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : hello
2021-09-03 13:17:11.664 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : hello
2021-09-03 13:17:32.714 INFO 11608 --- [ntLoopGroup-2-1] .BootNettyUdpSimpleChannelInboundHandler : ---------------------receive data--------------------------
感谢你能够认真阅读完这篇文章,希望小编分享的"Springboot中怎么用Netty开启UDP服务方式"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!