This is the sixth day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

An overview

The Socket mentioned above is a network application running on top of the TCP transport layer protocol. In addition to the TCP option, you can use the User Datagram Protocol (UDP), another transport-layer Protocol for sending data over IP that is fast but unreliable. When UDP data is sent, there is no way to know whether the data will arrive or whether the various parts of the data will arrive in the order in which they were sent. What does arrive, however, usually arrives quickly.

Maybe someone would consider it. If UDP is not a reliable data transfer protocol, why does it need to exist? In some applications, being the fastest is more important than getting every bit of data right. For example, when you’re watching a video, you won’t notice the occasional frame loss, but if frequent pauses are intolerable, UDP will work better than TCP in that case.

The differences between TCP and UDP can often be explained in terms of the telephone system and the post office. TCP is like the telephone system. When you dial, the phone is answered, creating a connection between the two parties. When you speak, you know the other party will hear you in the order you speak. If the phone is busy or no one answers, you’ll notice right away. UDP, by contrast, is like a post office system. You send a package to an address. Most letters arrive, but some can get lost along the way. Letters may arrive in the order they were sent, but this is not guaranteed. The farther away you are from the receiver, the more likely it is that the mail will get lost along the way or arrive out of order. If it’s important to you, you can number the envelope, then ask the recipient to order it in the correct order and send an email telling you which letters have arrived, so you can resend letters that didn’t arrive the first time. However, you and the other party need to negotiate this agreement in advance. The post office won’t do it for you. The telephone system and the post office have their uses. Although they can be used for almost any kind of communication, there are certain situations in which one is better than the other.

The implementation of UDP in Java is divided into two classes: DatagramPacket and DatagramSocket. The DatagramPacket class fills a UDP packet with bytes of data, called a datagram, and you unpack the received datagram. DatagramSocket can send and receive UDP datagrams. To send data, put the data into a DatagramPacket and use the DatagramSocket to send the packet. To receive data, you can receive a DatagramPacket object from the DatagramSocket and then examine the contents of the packet.

Unlike TCP

  1. UDP has no concept of a unique connection between two hosts. A Socket sends and receives all data pointing to a specified port, regardless of the remote host. A DatagramSocket can send and receive data from multiple independent hosts. Unlike TCP, this Socket is not dedicated to a connection. In fact, UDP has no concept of a connection between two hosts, only a single datagram. It is the application’s responsibility to determine who is sending what data.
  2. TCP sockets treat network connections as streams: data is sent and received through input and output streams from the socket. UDP does not support this, you are always dealing with a single datagram packet. All data populated in a datagram is sent as a packet and is either all received or lost as a group. One package is not necessarily related to the next. Given two packets, there is no way to determine which comes first and which comes later. Unlike streams, which must provide an orderly queue of data, datagrams swarm to the receiver as quickly as possible, like a large crowd of people crowding a bus. And in some cases, if the bus is too crowded, some bags, like some unlucky people, may be squeezed outside and continue to wait at the bus stop.

UDP example

In this example, the Client sends a packet to the Server. After receiving the packet, the Server parses the packet, extracts the source address and port number of the packet, and sends back the current time to the Client. The client outputs the time after receiving the datagram from the server.

UDP client

You first need to open a Socket to send and receive datagrams

DatagramSocket socket = new DatagramSocket(0);
Copy the code

The purpose of passing the 0 here is to let the operating system choose a port, because the client doesn’t care which port it sends from.

The next step is to set a timeout, in milliseconds. This step is optional, but necessary. Setting a timeout is even more important for UDP than TCP, because many of the problems that cause IOExceptions in TCP only quietly fail in UDP. For example, if the remote host is not listening on the target port, you will never hear back.

socket.setSoTimeout(4000);// Set the timeout period to 4s
Copy the code

Next you need to set up the packets. You set up two packets, one to send and one to receive. For this task, it doesn’t matter what data is in the sent datagram, what matters is the remote host and remote port to connect to. The packet that receives the server’s response contains only an empty byte array. The array should be large enough to contain the entire response.

InetAddress host = InetAddress.getByName("localhost");
DatagramPacket request = new DatagramPacket(new byte[1].1 , host, 5555);// Set the server port to 5555
DatagramPacket response = new DatagramPacket(new byte[1024].1024);
Copy the code

Then send a datagram on the open Socket and accept it. After getting the datagram returned by the server, get the data in it (the time returned by the server) output

socket.send(request);
socket.receive(response);
Copy the code

The code for UDPClinet as a whole is as follows:

import java.io.IOException;
import java.net.*;

public class DayTimeUDPClient {

    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(0);
        socket.setSoTimeout(4000);


        InetAddress host = InetAddress.getByName("localhost");
        DatagramPacket request = new DatagramPacket(new byte[1].1 , host, 5555);
        DatagramPacket response = new DatagramPacket(new byte[1024].1024);

        socket.send(request);
        socket.receive(response);

        String result = new String(response.getData(),0, response.getLength(),"US-ASCII"); System.out.println(result); }}Copy the code

UDP server.

The UDP server is similar to the UDP client. The difference is that the UDP server needs to receive packets before sending them. In addition, the Socket cannot be bound to an anonymous port because the CLIENT needs to know where to send UDP packets. Also, unlike TCP, UDP does not have a separate ServerSocket.

First, open a datagram Socket on a known port, set to 5555:

DatagramSocket socket = new DatagramSocket(5555);
Copy the code

Next, create a packet that will receive the request. Provide an array of bytes to store the inbound data, the offsets in the array, and the number of bytes to store. At this point, a packet that can store 1024 bytes starting at 0 is set up, and then the datagram is accepted. This call blocks indefinitely until a UDP packet reaches port 13. If a UDP packet arrives, Java populates the data in a byte array, and the Receive () method returns.

DatagramPacket request = new DatagramPacket(new byte[12].12);
socket.receive(request);
Copy the code

Then create a response packet. This consists of four parts: the raw data to send, the number of bytes of raw data to send, which host to send to, and which port on that host to send to. In this case, the raw data comes from a string of the current time, and the host and port are the hosts and ports of the inbound packets:

String daytime = new Date().toString();
byte[] data = daytime.getBytes("US-ASCII");
DatagramPacket response = new DatagramPacket(data, data.length,request.getAddress(), request.getPort());
Copy the code

Finally, the response is sent back through the same Socket that received the datagram with the following message:

socket.send(response);
Copy the code

The code for UDPServer is as follows:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;
import java.util.logging.Logger;

public class DayTimeUDPServer {
    private static final int PORT = 5555;
    private final static Logger audit = Logger.getLogger("requests");

    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(PORT);
        while (true)
        {
            DatagramPacket request = new DatagramPacket(new byte[12].12);
            socket.receive(request);

            String daytime = new Date().toString();
            byte[] data = daytime.getBytes("US-ASCII");
            DatagramPacket response = new DatagramPacket(data, data.length,request.getAddress(), request.getPort());
            socket.send(response);
            audit.info(daytime+"Client address:"+request.getAddress()+"Client port number:+request.getPort()); }}}Copy the code

The results of

As you can see in this example, UDP servers, unlike TCP servers, tend not to be multithreaded. They usually don’t do much for any one customer.

UDPServer results:

UDPClient results: