This is the 12th day of my participation in the August More Text Challenge. For details, see:August is more challenging

Introduction to the

In the previous series of articles, we looked at using Netty as the chat server, and the chat server uses SocketChannel, which means the underlying protocol uses socket. Today we will show you how to use UDP in Netty.

UDP protocol.

The User Datagram Protocol (UDP) is also called the User Datagram Protocol.

The main feature and highlight of UDP is not what features it introduces, but what it ignores: no guarantee of message delivery, no guarantee of delivery order, no tracking of connection status, and no need for congestion control.

Let’s look at a UDP packet:

UDP is a connectionless protocol. The sender only sends packets, and is not responsible for processing and ensuring whether the data is successfully sent, whether the data is processed. Its only function is to send.

Said in the JDK UDP have a special class called: java.net.DatagramPacket, in NIO. There is also a Java NIO. Channels. DatagramChannel, specifically responsible for handling the UDP channel.

Here we want to be netty, netty for UDP protocol also has the above two classes, although the name is the same, but the corresponding package is different. They are:

Io.net ty. Channel. The socket. The DatagramPacket and io.net ty. Channel. Socket. DatagramChannel, of course, these two classes of netty is the enhanced the JDK.

Netty DatagramPacket DatagramPacket

public class DatagramPacket
        extends DefaultAddressedEnvelope<ByteBuf, InetSocketAddress> implements ByteBufHolder 
Copy the code

The DatagramPacket class implements the ByteBufHolder interface, indicating that it holds ByteBuf. It then inherits from DefaultAddressedEnvelope, a class that encapsulates the address, where ByteBuf represents the type of message delivered, and InetSocketAddress represents the address of the destination, which is an IP address + port number encapsulation.

From the above UDP protocol, we know that UDP only needs to know the destination address and the corresponding message, so the data contained in DatagramPacket is sufficient.

DatagramChannel is used to pass DatagramPacket, and since DatagramChannel is an interface, NioDatagramChannel is generally used as the actual class.

String and ByteBuf conversion

As we’ve seen before, a channel in Netty only accepts ByteBuf data types, and if you write it directly to a String, you get an error. In previous articles, we’ve seen two ways to do this. The first way is to use ObjectEncoder and ObjectDecoder. Serialize objects. This is not only for Strings, but also for objects.

The second is to use StringEncoder and StringDecoder to specifically encode and decode strings. This processing can only handle String conversions, not objects.

If you don’t want to use these encoder and decoder, you can also use ByteBuf and String.

For example, to write a String to ByteBuf, call the Unpooled. CopiedBuffer command as follows:

Unpooled.copiedbuffer (" Start broadcasting ", charsetutil.utF_8)Copy the code

To convert ByteBuf to a String, call:

byteBuf.toString(CharsetUtil.UTF_8)
Copy the code

Build the DatagramPacket

DatagramPacket can take a total of three parameters: data to send, address to receive the packet, and address to send the packet.

For the client, we send a “start broadcast” message to the server, telling the server that it can send a reply message to the client, as follows:

New DatagramPacket (Unpooled copiedBuffer (" began to broadcast, "CharsetUtil. UTF_8), SocketUtils. SocketAddress (" 255.255.255.255." PORT))Copy the code

We use SocketUtils. SocketAddress created a special address, 255.255.255.255 is a special broadcast address, means that all of the host, because our client does not know the address of the server, so use 255.255.255.255 to broadcast.

The DatagramPacket is built with a sender() method, which can be used to get the address of the client, so you can build the packge to send on the server like this:

New DatagramPacket(unpooled.copiedBuffer (" broadcast: "+ nextQuote(), charsetutil.utF_8), packet.sender())Copy the code

Start the client and server

UDP client and server startup is slightly different from socket. If socket is used, NioSocketChannel is used; if UDP is used, NioDatagramChannel is used. Here is the server side startup code:

EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioDatagramChannel.class)
             .option(ChannelOption.SO_BROADCAST, true)
             .handler(new UDPServerHandler());

            b.bind(PORT).sync().channel().closeFuture().await();
        } finally {
            group.shutdownGracefully();
        }
Copy the code

Note that we need to set channeloption.so_broadcast to true because UDP sends messages as broadcast.

The client implementation is slightly different from the socket implementation. Here is the client startup implementation:

 EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
             .channel(NioDatagramChannel.class)
             .option(ChannelOption.SO_BROADCAST, true)
             .handler(new UDPClientHandler());

            Channel ch = b.bind(0).sync().channel();
Copy the code

For UDP, there is no address binding, so Bootstrap calls bind(0).

conclusion

This article explains the implementation of UDP protocol in Netty, UDP compared to Socket connection is much simpler.

An example for this article is learn-Netty4

This article is available at www.flydean.com/11-netty-ud…

The most popular interpretation, the most profound dry goods, the most concise tutorial, many you do not know the small skills waiting for you to find!

Welcome to follow my public number: “procedures those things”, understand technology, more understand you!