[Java Network Programming] Realize client-server communication based on UDP-Socket

Hello, everyone~ I am your old friend: Protect Xiao Zhou ღ  


This issue brings you the UDP Socket socket of network programming. The Socket based on the UDP protocol realizes the communication between the client and the server . The Socket socket can be understood as a set of APIs provided by the transport layer to the application layer. Such a program , make sure you don't want to see it~~


This issue is included in the blogger's column : JavaEE_Protect Xiao Zhouღ's Blog-CSDN Blog

Suitable for programming beginners, interested friends can subscribe to view other "JavaEE Basics".
Stay tuned for more highlights: Protect Xiaozhou ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★*'


Socket can be understood as a set of APIs (interfaces) for network programming provided by the operating system to programmers - the interface of the transport layer, and a set of APIs provided by the transport layer to the application layer, collectively referred to as Socket API. The underlying logic of network communication has been encapsulated by the operating system, and developers can implement network communication based on interface development.

Socket sockets are mainly divided into the following three categories for transport layer protocols:

  • Byte stream socket: use transport layer TCP protocol
  • Datagram sockets: use the transport layer UDP protocol
  • Raw sockets: for custom transport layer protocols

 This blog mainly talks about datagram-oriented network programming.


1. Java-based UDP datagram socket communication model

Features of the UDP protocol:

  1. Connectionless: before transmitting data, the communicating parties do not depend on establishing a connection, but only need to know who is sending it to whom.
  2. Unreliable transmission: only responsible for sending, do not pay attention to whether the data is transmitted successfully, even if the transmission is not successful, do nothing, and there is no feedback
  3. Datagram-oriented: UDP datagrams are used for transmission, and datagrams can be understood as data being transmitted piece by piece.
  4. There is the concept of a buffer area: receiving buffer, sending buffer: a buffer for storing data to be sent or received during network data communication.
  5. The size of data transmission is limited: a UDP datagram can occupy a maximum of 64k, 1k = 1024 bytes
  6. Full-duplex communication: Both communication parties can exchange information at the same time

Summary: The UDP protocol has the characteristics of connectionless and datagram-oriented. Even if the communication parties have not established a connection, data will be transmitted, and all datagrams will be sent at one time, and all datagrams will be accepted at one time.

UDP-based communication in Java mainly uses  the DatagramSocket class to create a datagram socket, and uses
DatagramPacket as the UDP datagram to send or receive.


A client sends a request to the server, and the server responds to the request as follows:

​In a real network environment, a server often provides responses to multiple clients.

Let’s take a practical example and understand it according to the above flowchart. Mr. Zhang San used the Baidu browser of his mobile phone to search for "beauty pictures". At this time, the front-end page will take this search record "beauty pictures" to the background and package it into a UDP datagram. , sent to the Baidu server in the form of a request. After receiving the request, the Baidu server parses the datagram to check: Oh~ I want beauties, I have a lot of them, so I respond to the "locally" stored beauties pictures as UDP datagrams. On the request side, after Baidu browser gets the response data from Baidu server, it parses the picture and displays the picture on the interface of Zhang San's mobile phone.


2. UDP datagram socket programming

2.1  DatagramSocket API

DatagramSocket is a class for Socket sockets to send and receive datagrams based on the UDP protocol.

Datagram : Datagram

Socket: Indicates that this object is a Socket object

The Socket object is equivalent to a special file of the operating system. This file does not correspond to a certain data storage area on the corresponding hard disk, but corresponds to the hardware of the network card! ! !

Writing data to the socket object is equivalent to sending a message through the network card

Reading data from the socket object is equivalent to receiving messages through the network card

Therefore, if you want to perform network programming to enable two devices to communicate with each other, you need an object such as a socket file, and use this socket file object to indirectly operate the network card. The basic design idea of ​​​​the operating system: everything is a file, in order to simplify the logical design of the system kernel , the socket object reads and writes byte streams .


The Socket object here can be used by the client/server. The Socket on the server side must be associated with a specific port number. Each networked device will be bound to a The unique identification of the program is equivalent to the data being received by your device. After analysis, you need to know which application program the data needs to be processed. For example, qq and WeChat have never seen a situation where messages are posted in a row.

There is no need to specify manually on the client side, the system will automatically assign randomly, and the value range of the port number is [0, 65535].

Port numbers less than or equal to 1024 will be used by well-known servers, and this category is not recommended.


Socket is also a file, and the resource must be closed when it is used up.


2.2  DatagramPacket API

The DatagramPacket class is used for datagrams sent and received by Socket based on UDP protocol.

The version with only two parameters does not need to design an address, and is usually used to receive messages. Another multi-parameter version requires an explicit address to be set, and is usually used to send messages.


When constructing the datagram sent by UDP, the socketAddress object needs to be passed in, and this object can be created using InetSocketAddress.

The constructor of the InetSocketAddress API:


 3. Implement client and server programs based on UDP Socket

Functions of programs that analyze clients:

1. Make a request (message)

2. Wait for the server to respond (response)

3. Parse the server's response

Analyze the function of the server-side program:
1. Try to read the client's request and parse it

2. Coordinate the response data according to the client's request

3. Return the response to the client


3.1 Server program design

First we define a server class: UdpEchoServer

Define a Socket object file to interact with the network card.

//需要线定义一个 socket 对象
//通过网络通信,必须要使用 socket 对象
private DatagramSocket socket = null;

Use  the construction method of the UdpEchoServer class  to construct the socket  , and specify the port number to be bound

  public UdpEchoServer(int serverPort) throws SocketException {
        //构造 socket 的同时,指定要的关联/ 绑定的端口
        socket = new DatagramSocket(serverPort);
  }

Binding a port may not be successful. If a port is already occupied by another process, an error will occur in the binding operation here. At the same time, a port on a host can only be bound by one process at the same time. Certainly. So an exception is thrown here.


Define a startup method: start() 

The method adopts a loop method inside, and each loop does three things:

1. Read and parse the request, 2. Calculate the response based on the request, 3. Write the result of the response back to the client

public void start() throws IOException {
        System.out.println("服务器启动!");
        while (true) {
            // 每次循环,要做三件事情:
            // 1. 读取请求并解析
            // 构造接受请求的“空盒子”,指定盒子的大小 4096 字节
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
            // 数据从网卡上来的
            socket.receive(requestPacket);// 获取客户端的请求、

            //为了方便处理这个请求,把二进制数据转换成 String
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            // 2. 根据请求计算响应 调用方法
            String response = process(request);

            /* 3. 把响应结果写回客服端
            根据response 字符串,构造一个 DatagramPacket
            和请求 packet 不同,此处构造响应的时候,需要指定这个包要发给谁 */
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length, requestPacket.getSocketAddress());
            // response.getBytes() 转换为 byte二进制流
            // requestPacket 是从客户端这里收来的,getSocketAddress 就会得到客户端的 IP 和 端口
            socket.send(responsePacket);// 响应
            // 可以保存以下日志
            String now3 = df.format(System.currentTimeMillis()); // 返回当前系统时间
            try(Writer writer = new FileWriter("outPut.txt", true)) {
                writer.write(requestPacket.getAddress().toString() +
                        requestPacket.getPort() + " " + now3 +
                        " req: " + request + " resp:  " + response + "\n");
            }
            // 打印一下本次客户端与服务端的交互
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(), request, response);
        }
    }
 public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();

    }

2. According to the client's request, we will coordinate the response data, and we will encapsulate the second step to calculate the response in the form of a function. The parameter request request has been converted into a string, so we can make corresponding processing according to the request. If you need to search for something, you can return the searched content stored in the server as a response to the client according to the requested content. If you want to send messages to each other, you need to judge who needs to send them based on the request. At this time, both parties need to agree Add the receiver's IP and port to the request, so that the receiver can be found. As a server, it needs to use the idea of ​​multi-threading. Every request sent by the client will be allocated a thread to process.

    public String process(String request) { //这里直接将客户端的请求,作为响应返回
        return "服务器响应:" + request;
    }

This part can perform corresponding business processing according to the client's request.


3.2 Client program design

First define a client class: UdpEchoClient 

Define a Socket object file to interact with the network card.

Define the member variable of serverIP to store the IP address of the server

Define the member variable of serverPort to store the port number of the server

private DatagramSocket socket = null;
private String serverIP = null; // IP
private int serverPort = 0; // 端口号 —— 代表进程的标识

Use  the construction method of the UdpEchoClient class  to construct the socket  , and associate the IP address and port of the server with the member method

   //客户端启动,需要知道服务器在哪儿!!
    public UdpEchoClient(String serverIP, int serverPort) throws SocketException {
        //对于客户端来说,不需要显示关联端口
        // 不代表没有端口,而是系统自动分配了个空闲的端口
        socket = new DatagramSocket(); //获取随机端口号
        this.serverIP = serverIP;
        this.serverPort = serverPort;
    }

Define a startup method: start() 

The method uses a loop method inside, and each loop does 4 things:

1. Get the information entered by the user from the console

2. Construct the obtained information into a UDP datagram and send a request to the server

3. The client tries to read the response returned by the server

4. Further process the obtained response according to business needs

public void start() throws IOException {
        // 通过这个客户端可以多次和服务器进行交互
        System.out.println("客户端启动!");
        Scanner in = new Scanner(System.in);
        while (true) {
            //1.先从控制台,读取一个字符串过来
            //先打印一个提示符,提示用户要输入内容
            System.out.print("->");
            String request = in.next();

            //2. 把字符串构造成 UDP packet, 并进行发送
            DatagramPacket requestPacket = new DatagramPacket(
                    request.getBytes(),
                    request.getBytes().length,
                    //----如果参数为null,获得的是本机的IP地址
                    InetAddress.getByName(serverIP),// 确定主机的 IP 地址----在给定主机名的情况下确定主机的IP地址
                    serverPort);
            socket.send(requestPacket); //响应

            //3. 客户端尝试读取服务器返回的响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);

            //4. 把响应的数据转换成 String 显示出来,利用 String 的构造方法转换
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.printf("req: %s, resp: %s\n", request, response);
        }
    }
 public static void main(String[] args) throws IOException {
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        udpEchoClient.start(); // 启动客户端
    }

3.3 Summary:

The above client server code uses the Socket "file stream", but does not call the close() method to release resources, because the file stream will be closed as the process is closed, but you must remember to close it in actual development~

Start the client and server to display the effect:

 Execution diagram of the above operation process.

 Be sure to start the server first, then start the client,

UDP (User Datagram Protocol) is a connectionless transport layer protocol, which does not guarantee reliable transmission of data packets. UDP is faster than TCP and is used in situations where network latency is low and data accuracy is not critical. This article will discuss the summary of client server development based on UDP Socket.

UDP Socket

Socket is an API (Application Programming Interface) for communicating between computers. UDP Socket is a socket for communication based on the UDP protocol. It provides a fast way to send and receive data packets, but unlike TCP, it does not repeat data or check for missing data packets.

The basic steps to write a UDP client are as follows:

  1. Create a UDP socket.
  2. Pack the data to be sent into UDP packets.
  3. Use UDP socket to send data packets to specific IP address and port number.

The basic steps to write a UDP server are as follows:

  1. Create a UDP socket and listen on a specific port number.
  2. Receive packets sent by the client.
  3. Process the packet, then pack the response into another UDP packet.
  4. Send a response packet to the client using UDP socket.

Summarize:

When using UDP Socket for client and server development, you need to pay attention to the following points:

  • UDP does not guarantee reliable delivery of packets, so packet loss or corruption needs to be handled in the application.
  • Since UDP has no connection state, it can communicate with multiple clients at the same time.
  • In UDP communication, the destination address and port number need to be specified.

Ok, so here,  the UDP-Socket-based implementation of client and server communication bloggers in network programming has finished sharing. I hope it will be helpful to everyone. If there is any inappropriateness, welcome to criticize and correct. 

Next issue preview: TCP protocol

Thank you to everyone who read this article, and more exciting events are coming: Protect Xiaozhou ღ *★,°*:.☆( ̄▽ ̄)/$:*.°★* 

When I met you, all the stars fell on my head ...

Guess you like

Origin blog.csdn.net/weixin_67603503/article/details/130247537