Using Netty to Open UDP Service Mode in Springboot
- 2021-12-12 08:24:00
- OfStack
Netty
Netty is a network programming tool and an excellent package for socket programming. It supports TCP, UDP, FTP and other protocols. We can use Netty to develop our own http server, udp server, FTP server, RPC server and so on
Why Netty is so popular:
Concurrent highNetty supports NIO programming, and NIO supports, which can greatly improve concurrent performance.
Fast transmissionOne feature of Netty NIO is zero copy, which directly opens up one block in memory and leaves socket buffer.
EncapsulatedNext, write a simple udp demo. General idea:
Write an Server based on UDP of netty to accept data Write a 1 processing class to process the accepted data and then return the information
Create a new springboot project. Introducing jar into pom
pom.xml
<!--springboot version I'm using 2.1.3.RELEASE-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.3.RELEASE</version>
</dependency>
<!--web Initiator of module -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- netty Dependency springboot2.x Automatically import version -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<!-- I used it here @slf4j So introducing this jar -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
Create NettyUDPServer
Types of Channel channels
NioSocketChannel
That represents an asynchronous client TCP Socket connection.
NioServerSocketChannel
Asynchronous server-side TCP Socket connection.
NioDatagramChannel
Asynchronous UDP connection
NioSctpChannel
Asynchronous client Sctp connection.
NioSctpServerChannel
Asynchronous Sctp server-side connection.
OioSocketChannel
Synchronized client TCP Socket connection.
OioServerSocketChannel
Synchronized server-side TCP Socket connection.
OioDatagramChannel
Synchronized UDP Connection
OioSctpChannel
Synchronized Sctp server-side connection.
OioSctpServerChannel
Synchronized client TCP Socket connection.
Bootstrap is a convenient factory class provided by Netty, which can be used to initialize Netty on the client or server side of 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
*/
@Slf4j
public class BootNettyUdpServer {
/**
* Startup service
*/
public void bind(int port) {
log.info("-------------------------------udpServer-------------------------");
// Represents a server connection listening thread group that specifically accepts accept New client client Connect
EventLoopGroup bossLoopGroup = new NioEventLoopGroup();
try {
//1 , creating netty bootstrap Startup class
Bootstrap serverBootstrap = new Bootstrap();
//2 , setting boostrap Adj. eventLoopGroup Thread group
serverBootstrap = serverBootstrap.group(bossLoopGroup);
//3 , setting NIO UDP Connection channel
serverBootstrap = serverBootstrap.channel(NioDatagramChannel.class);
//4 Setting channel parameters SO_BROADCAST Broadcast form
serverBootstrap = serverBootstrap.option(ChannelOption.SO_BROADCAST, true);
//5 Setting up the processing class Assembly line
serverBootstrap = serverBootstrap.handler(new BootNettyUdpSimpleChannelInboundHandler());
//6 , binding server By calling the sync The () method blocks asynchronously until the binding succeeds
ChannelFuture f = serverBootstrap.bind(port).sync();
log.info(BootNettyUdpServer.class.getName()+" started and listend on "+f.channel().localAddress());
//7 Listening for channel closure events, the application will 1 Wait until channel Shut down
f.channel().closeFuture().sync();
} catch (Exception e) {
// TODO: handle exception
} finally {
System.out.println("netty udp close!");
//8 Shut down 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
*/
@Slf4j
public class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
try {
String strdata = msg.content().toString(CharsetUtil.UTF_8);
// Print the received message
log.info("---------------------receive data--------------------------");
log.info(strdata);
log.info("---------------------receive data--------------------------");
// Received udp Message, you can return the message in the same way, such as return timestamp
ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("ok", CharsetUtil.UTF_8), msg.sender()));
} catch (Exception e) {
}
}
}
Modify the startup class, start the execution of UDPServer. bind method, and start udpServer
@SpringBootApplication
@EnableAsync
public 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
Under the test class, create a new test method
sendUdpRequestTest
// Define the client ip
private static final String SERVER_HOSTNAME = "127.0.0.1";
// Server port
private static final int SERVER_PORT = 51000;
// Local send port
private static final int LOCAL_PORT = 8888;
@Test
public void sendUdpRequestTest() {
try {
// 1 , creating udp Service. Pass DatagramSocket Object.
DatagramSocket socket = new DatagramSocket(LOCAL_PORT);
// 2 Identify the data and encapsulate it into a data packet. 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 , through socket Service, sending out the existing data packets. Pass send Method.
socket.send(dp);
// 4 Close the resource.
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Results
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: Hello, World
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: Hello, World
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--------------------------