02_ UDP protocol for Java network programming

Posted by CapEsiouS on Tue, 21 Dec 2021 21:12:02 +0100

0. General

In a technical sense, because TCP needs to establish a connection, UDP can "throw vegetables" directly

Therefore, only TCP protocol has Server server and Client client. For UDP protocol, there is no Server and Client

UDP protocol features:

  • UDP is a connectionless and unreliable transmission protocol
  • Encapsulate the data source IP, destination IP and port as well as data into data packets with the size limited to 64KB and send them directly

Therefore, for example, UDP protocol is like throwing vegetables across the road in a small video

People (datagram socket sender receiver object) are required to throw vegetables (data), and a dish (datagram packet object) is also required to load vegetables

1. Objects in UDP communication

1.1 datagram packet: datagram packet object

  • It can be used as a plate for vegetables
  • A packet that represents a datagram
  • Check the source code and find that this class is an immutable object modified by final
  • Constructor:
constructor explain
public DatagramPacket(byte[] buf, int length, InetAddress address, int port)Create a sender packet object,
buf: content to be sent, byte array,
Length: the byte length of the content to be sent,
Address: the IP address object of the receiving end
Port: the port number of the receiving end
public DatagramPacket(byte[] buf, int length)Create a packet object at the receiving end. buf: used to store the received content. Length: the length of the content that can be received
  • Common API:
methodexplain
public int getLength()Returns the number of bytes actually received or the length of data to be sent
byte[] getData()Returns the data in the packet
InetAddress getAddress()Returns the IP address of the computer that sent or received the datagram
If not set, the IP address of the machine is returned
SocketAddress getSocketAddress ()Returns the SocketAddress of the remote host that sent or received the datagram
(usually IP address plus terminal slogan)
int getPort()Returns the port number on the remote host that sent or received data, or 0 if not set

1.2 datagram socket: sender and receiver objects

  • It can be understood as the person throwing vegetables
  • Socket for sending and receiving datagrams
  • Implemented Java io. The closeable interface can be defined in try() and then automatically released
  • Constructor:
constructor explain
public DatagramSocket()Create a Socket object at the sending end, and the system will randomly assign a port number
public DatagramSocket(int port)Create the Socket object of the receiving end and bind the specified port number on the local host
It's not impossible for you to create a sender object with this
  • Common API:
methodexplain
public void send(DatagramPacket dp)Send packet
public void receive(DatagramPacket p)Receive the data packet and load the received data directly into the byte array of p

2. One UDP communication sends and one receives

2.1 implementation steps of client (sender)

  1. First create the sending end object datagramsocket (you can only throw dishes when there are people, and create people first and then create dishes)
  2. Create a data packet object datagram packet to encapsulate the data to be sent and the IP address and port number of the other party
  3. Use the send method of the DatagramSocket object and pass in the DatagramPacket object as the parameter (I start throwing vegetables ~ ~)
  4. Release resources
  5. Note: if the sender is started first, an error will be reported, and the receiver must be started first

Sender code example:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;

/**
 * TCP Client in UDP, sender in UDP
 */
public class SenderDemo {
    public static void main(String[] args) {
        System.out.println("Sender start~~~~Sobbing, sobbing, sobbing");
        try (
            // First create the sender object (the person throwing vegetables)
            DatagramSocket socket = new DatagramSocket();
                ){
            // First create a byte array to encapsulate data (DISH)
            byte[] buffer = "I mean, don't throw leeks around,What a terrible dish".getBytes(StandardCharsets.UTF_8);

            // Create a packet object (DISH) and specify the IP address and port number of the receiving end
            DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
                    InetAddress.getLocalHost(), 8888);

            // Throw vegetables!!!!
            socket.send(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.2 implementation steps of receiving end

  1. Create the receiving end object DatagramSocket and specify the port (person)
  2. Create a data packet object DatagramPacket to receive data (tray). The recommended array size for receiving data is 1024 * 64, because the maximum size of a UDP data packet is 64kb
  3. Use the receive method of the datagram socket object to pass in the datagram packet object as a parameter (I'll pick up your dish ~ ~), and the thread will block until the data is received
  4. Note: start the server (receiver) first and then the client (sender)
  5. Take out the data. Note: how much is received and how much is read (use the getLength() method of the tray)
  6. Release resources

Receiver code example:

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiverDemo {
    public static void main(String[] args) {
        System.out.println("Server side startup~~~~Doodle doodle doodle doodle");
        try (
            // When creating a receiver object (person), the port number must be consistent with that of the sender packet object
            DatagramSocket socket = new DatagramSocket(8888);
                ){
            // Create packet object to receive data (tray)
            byte[] bytes = new byte[1024*64];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);

            // Waiting to receive data
            // After the server is started, it will always wait to receive data
            socket.receive(packet);

            // Read data
            String str = new String(bytes, 0, packet.getLength());
            System.out.println("Data received:" + str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. Analog multiple transmit multiple receive of UDP communication

Multiple sending and multiple receiving:

  • The sender can always send messages
  • The receiving end can continuously receive the message display of multiple sending ends
  • If the sender inputs exit or other end information, the sender ends the program

3.1 implementation steps of sender

  1. Create the sending end object DatagramSocket (the person throwing vegetables)
  2. Use the while loop to continuously receive data input. If the input exit, exit the program (IO stream can be used)
  3. If the input is not exit, package the data into a datagram packet and specify the IP address and port number of the receiving end
  4. Use the send method of DatagramSocket object to send the packet object (throwing dishes ~ ~)
  5. Release resources

Example:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * TCP Client in UDP, sender in UDP
 */
public class SenderDemo {
    public static void main(String[] args) {
        System.out.println("Sender start~~~~Sobbing, sobbing, sobbing");
        try (
            // First create the sender object (the person throwing vegetables)
            DatagramSocket socket = new DatagramSocket();
                ){
            Scanner in = new Scanner(System.in);
            // Create an endless loop and keep reading data until you read exit
            while (true) {
                System.out.println("Please enter the content to send:");
                String str = in.nextLine();

                // Judge whether it is exit
                if ("exit".equals(str)){
                    System.out.println("Offline success,bye~~");
                    break;
                }

                // First create a byte array to encapsulate data (DISH)
                byte[] buffer = str.getBytes(StandardCharsets.UTF_8);

                // Create a packet object (DISH) and specify the IP address and port number of the receiving end
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
                        InetAddress.getLocalHost(), 8888);

                // Throw vegetables!!!!
                socket.send(packet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.2 implementation steps of receiving end

  1. Create the receiving end object DatagramSocket and specify the port (the person throwing vegetables)
  2. Create a data packet object DatagramPacket to receive data (dishes). The recommended array size is 1024 * 64
  3. Use the while loop to continue step 4
  4. Use the receive method of the datagram socket object to pass in the datagram packet object (pick up the dish)

be careful:

  • At this time, the receiver is only responsible for receiving data packets, because UDP does not need to establish a connection, and it doesn't matter which sender's data packets
  • Therefore, the receiver of UDP can receive many messages from the sender
  • TCP must use multithreading to receive a lot of sender information, because TCP needs to establish a connection

Example:

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class ReceiverDemo {
    public static void main(String[] args) {
        System.out.println("Server side startup~~~~Doodle doodle doodle doodle");
        try (
            // When creating a receiver object (person), the port number must be consistent with that of the sender packet object
            DatagramSocket socket = new DatagramSocket(8888);
                ){
            // Create packet object to receive data (tray)
            byte[] bytes = new byte[1024*64];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);

            // The write cycle continuously receives data
            while (true) {
                // Waiting to receive data
                // After the server is started, it will always wait to receive data
                socket.receive(packet);

                // Read data
                String str = new String(bytes, 0, packet.getLength());
                System.out.println("Received from" + packet.getAddress() + "Data,The opposite port is:"
                        + packet.getPort() + ",Data is:" + str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4. Three communication modes of UDP

  • Unicast: the communication between a single host and a single host is unicast
  • Broadcast: the current host communicates with all hosts in the network
  • Multicast: the communication between the current host and a selected group of hosts can be understood as a group of hosts subscribing to a certain multicast IP, and the multicast IP update will push tweets to the followers

4.1 broadcast implementation steps

  • Use broadcast address: 255.255 255.255. If you specify another port, it will be given to the corresponding port of other hosts in the same network segment as the host (including the corresponding port of the host)

  • Specific steps:

    The destination of the packet sent by the sender is the broadcast address and the port is specified. (255.255.255.255 , 8888)
    Programs of other hosts in the local network segment can receive messages as long as they register the corresponding port. (8888)

    Network segment: for example, if the first three digits of the IP address are the same, they are in the same network segment

  • Therefore, you only need to modify the source code of the sender. Code example:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/**
 * TCP Client in UDP, sender in UDP
 */
public class SenderDemo {
    public static void main(String[] args) {
        System.out.println("Sender start~~~~Sobbing, sobbing, sobbing");
        try (
            // First create the sender object (the person throwing vegetables)
            DatagramSocket socket = new DatagramSocket();
                ){
            Scanner in = new Scanner(System.in);
            // Create an endless loop and keep reading data until you read exit
            while (true) {
                System.out.println("Please enter the content to send:");
                String str = in.nextLine();

                // Judge whether it is exit
                if ("exit".equals(str)){
                    System.out.println("Offline success,bye~~");
                    break;
                }

                // First create a byte array to encapsulate data (DISH)
                byte[] buffer = str.getBytes(StandardCharsets.UTF_8);

                // Create a packet object (DISH) and specify the IP address and port number of the receiving end
                //!!!! Note: use broadcast to modify the IP address here to 255.255 255.255 is enough!!!!!!!
                DatagramPacket packet = new DatagramPacket(buffer, buffer.length,
                        InetAddress.getByName("255.255.255.255"), 8888);

                // Throw vegetables!!!!
                socket.send(packet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.2 multicast implementation steps

  • Use multicast address: 224.0 0.0 ~ 239.255. 255.255 with address 224.0 0.0 is reserved and should not be used

  • The sender selects a multicast IP (e.g. 224.0.1.1) from the multicast address and specifies the port number

  • The receiving end must bind the multicast IP(224.0.1.1) and register the port number specified by the sending end to receive multicast information

  • Binding multicast IP at the receiving end:

    Multicast socket, a subclass of datagram socket, can bind multicast IP at the receiving end

    Therefore, his son MulticastSocket is used when creating the receiver object (person)

    His son has practiced all kinds of magic skills, and his ability to pick up vegetables is even better

    Call the join group (InetAddress. Getbyname ("multicast IP") = = method of the = = MulticastSocket to bind the multicast IP

    But this method became obsolete in JDK14

    Example:

MulticastSocket socket = new MulticastSocket(8888);
socket.joinGroup(InetAddress.getByName("224.1.1.1"));
  • Timeless approach:

    joinGroup(SocketAddress mcastaddr, NetworkInterface netIf);
    // Parameter 1 is SocketAddress, which can be obtained in the following ways:
    new InetSocketAddress(InetAddress.getByName("224.1.1.1"), 8888);
    // The second parameter is to declare the network segment where the receiving end is located, so that the sub can accept the information sent by the host in the same network segment
    // We generally use the default network segment where the current host is located (generally LAN):
    NetworkInterface.getByInetAddress(InetAddress.getLocalHost();
    

Therefore, the implementation of multicast should not only change the source code of the sender, but also modify the source code of the receiver

The source code of the sender can be changed to the multicast IP, which is consistent with the steps of the sender changing to the broadcast mode, and will not be shown

Receiver code example:

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class ReceiverDemo {
    public static void main(String[] args) {
        System.out.println("Server side startup~~~~Doodle doodle doodle doodle");
        try (
                // When creating a receiver object (person), the port number must be consistent with that of the sender packet object
                MulticastSocket socket = new MulticastSocket(8888);
                ){
            // Bind the receiver object to the multicast IP
            socket.joinGroup(InetAddress.getByName("224.1.1.1"));

            // Create packet object to receive data (tray)
            byte[] bytes = new byte[1024*64];
            DatagramPacket packet = new DatagramPacket(bytes, bytes.length);

            // The write cycle continuously receives data
            while (true) {
                // Waiting to receive data
                // After the server is started, it will always wait to receive data
                socket.receive(packet);

                // Read data
                String str = new String(bytes, 0, packet.getLength());
                System.out.println("Received from" + packet.getAddress() + "Data,The opposite port is:"
                        + packet.getPort() + ",Data is:" + str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5. Real time communication

Implementation steps:

  1. Create a sender class, use multithreading and IO stream to read and write data, and encapsulate member variables such as port number and IP address
  2. Create a receiver class, use multithreading and IO stream to read and write data, and encapsulate user name, port number and other member variables
  3. Two classes are defined, both of which instantiate the sender and receiver to realize real-time communication

Topics: Java network udp