Using Netty to Open UDP Service Mode in Springboot

  • 2021-12-12 08:24:00
  • OfStack

Directory Netty creates a new springboot project. Introducing jar into pom, creating NettyUDPServerNettyUdpSimpleChannelInboundHandler modification startup class, starting execution of UDPServer. bind method, starting udpServertest result

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 high

Netty supports NIO programming, and NIO supports, which can greatly improve concurrent performance.

Fast transmission

One feature of Netty NIO is zero copy, which directly opens up one block in memory and leaves socket buffer.

Encapsulated

Next, 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--------------------------


Related articles: