Network programming - UDP datagram socket

Column introduction: JavaEE from entry to advanced

Topic source: leetcode, Niuke, Jianzhi offer.

Creation goal: record the learning process of learning JavaEE

I hope to help others while improving myself, and make progress together with everyone and grow up with each other.

Academic qualifications represent the past, ability represents the present, and learning ability represents the future! 


Table of contents

1. Basics of network programming

1.1 Why do you need network programming?

1.2 What is network programming?

1.3 Basic concepts in network programming

2. Socket socket

2.1 Java Datagram Socket Model 

2.2 Java stream socket communication model

 2.3 Notes on Socket programming

3. UDP datagram socket programming

3.1 DatagramSocket API

3.2 DatagramPacket API

3.3 NetSocketAddress API

Example 1: echo server

Example 2: Look up dictionary server 


1. Basics of network programming

1.1 Why do you need network programming?

When a user opens an online video website, such as Tencent Video, in a browser, he actually obtains a video resource on the network through the network.

Similar to opening a local video file, except that the source of the video resource is the network. Compared with the local video, the network provides more abundant network resources.

The so-called network resources are actually all kinds of data resources that can be obtained in the network.

And all network resources are used for data transmission through network programming .


1.2 What is network programming?

Network programming refers to the fact that hosts on the network implement network communication (network data transmission) programmatically through different processes (ports) 

In fact, network transmission only needs to satisfy different processes, so even if it is the same host, network transmission can be performed as long as they are different processes .

For developers, under limited conditions, network programming is performed on the same host.

However, we must be clear that our purpose is to provide different hosts on the network to transmit data resources based on the network.

  • Process A, programming to obtain network resources
  • Process B, programmed to provide network resources

1.3 Basic concepts in network programming

sender and receiver

When the network data is transmitted again:

Sender : The sender process of the data , and the sender host is the source host in network communication.

Receiver : The receiver process of the data , and the receiver host is the destination host in network communication.

Transceiver : The two ends of the transmitter and the receiver, referred to as the transceiver.

Tips: The sending end and the receiving end are relative, just a concept of data flow generated by a network data transmission.


request and response

Generally speaking, obtaining a network resource involves two network data transmissions:

  • First time: Sending of request data
  • Second time: sending of response data

For example, ordering fried chicken at a fast food restaurant:

The first thing to do is to initiate a request: order a piece of fried chicken, and then the fast food restaurant provides a corresponding response: provide a piece of fried chicken.


client and server

Server : In common network data transmission scenarios, the process that provides services is called a server, which can provide external services.

Client : A process that obtains services is called a client.

For services, generally provide:

  • The client obtains service resources.

  • The client saves resources on the server.


Common client server model

1. The client first sends a request to the server.

2. The server executes the corresponding business processing according to the request data.

3. The server returns a response and sends the processing result of the business. 

4. The client displays the processing results based on the response data (displays the obtained resources, or prompts to save the processing results of the resources).


2. Socket socket

concept:

Socket is a technology provided by the system for network communication, and is the basic operation unit of network communication based on TCP/IP protocol. The development of network programs based on Socket is network programming.


Classification:

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

Stream socket :

Use the transport layer TCP protocol, that is, Transmission Control Protocol (Transmission Control Protocol), transport layer protocol.

Features of TCP :

  • connected
  • reliable transmission
  • stream-oriented
  • There are receive buffers and send buffers. (Full duplex)
  • Any size

For the byte stream, it can be simply understood that the transmission data is based on the IO stream, and the characteristic of the stream data is that when the IO is not closed, it is unbounded data, which can be sent multiple times or received multiple times separately .


Datagram sockets :

Use the transport layer UDP protocol, namely User Dategram Protocol (User Datagram Protocol), transport layer protocol.

Features of UDP:

  • no connection
  • unreliable transmission
  • Datagram Oriented
  • There are receive buffers and send buffers (full duplex)
  • Any size

For datagrams, the transmission data is piece by piece. When sending a piece of 100-byte data, it must be sent at one time, and the reception must also receive 100 bytes at a time, instead of dividing it into 100 times, and receiving one byte at a time.


raw socket

Raw sockets are used to customize the transport layer protocol, and are used to read and write IP protocol data that the kernel does not process.


2.1 Java Datagram Socket Model 

For UDP datagrams, it has the characteristics of connectionless and datagram-oriented, that is, no connection is established every time, and all datagrams are sent at one time, and all datagrams are received at one time.

Java always uses the UDP protocol for communication, mainly based on the DatagramSocket class to create datagram sockets, and use DatagramPacket  to send or receive UDP datagrams. The corresponding process for sending and receiving datagrams is as follows:


 2.2 Notes on Socket programming

  • 1. Client and server : During development, two processes are often opened based on one host as the client and server, but the real scenario is generally different hosts.
  • 2. Pay attention to the destination IP and destination port number , which identify the end host and process to send data during a data transmission.
  • 3. Socket programming we use stream sockets and datagram sockets, based on the TCP or UDP protocol of the transport layer, but the      application layer protocol also needs to be considered, and the follow-up will introduce how to design the application layer protocol.
  • 4. If a process A binds a port, and then starts a process B to bind the port, an error will be reported. This situation is also called the port is occupied .

3. UDP datagram socket programming

3.1 DatagramSocket API

DatagramSocket is a UDP socket for sending and receiving datagrams.

DatagramSocket construction method:

method signature Method Description
DatagramSocket() Create a UDP datagram socket Socket, bind any random port of this machine (commonly used for clients)
DatagramSocket(int prot) Create a UDP datagram socket Socket, bind to the port specified by the machine (generally used for the server)

DatagramSocket method:

method signature Method Description
void receice(DatagramPacket p) Receive a datagram from this socket (if no datagram is received, this method will block waiting)
void send(DatagramPacket p) Send a datagram from this socket (directly, no blocking wait)
void close() Close the secondary datagram socket

3.2 DatagramPacket API

DatagramPacket is the datagram sent and received by UDP Socket.

DatagramPacket construction method:

method signature Method Description
DatagramPacket(byte[] buf,int length) Construct a DatagramPack to receive the datagram, the received datagram is stored in the byte array (the first parameter buf), and the specified length (the second parameter length)
DatagramPacket(byte[] buf,int offset,int length,SocketAddress address) Construct a DatagramPacket to send data, the sent data is a byte array, from 0 to the specified length, address specifies the IP and port number of the host

DatagramPacket method:

method signature Method Description
InetAddress getAddress() Obtain the IP address of the sending host from the received datagram; or obtain the IP address of the receiving host from the sent datagram.
int getPort() Get the port number of the sending host from the received datagram; or get the port number of the receiving host from the sent datagram.
byte[] getData() Get the data in the datagram

When constructing the datagram sent by UDP, you need to pass in SocketAddress , which can be created using InetSocketAddress .


3.3 NetSocketAddress API

InetSocketAddress (subclass of SocketAddress) constructor:

method signature Method Description
InetSocketAddress(InetAddress addr , int port) Create a Socket address, including IP address and port number

Example 1: echo server

General server operations: receive the request, calculate the response based on the request, and return the response

The echo server omits the "calculate the response based on the request", and returns whatever the request is. (The server has no actual business, but just shows the basic usage of the socket api)

public class UdpEchoServer {
    //网络编程本质上是操作网卡
    //但网卡不方便直接操作 , 在操作系统内核中 , 使用一种特殊的叫做"socket"这样的文件来抽象表示网卡
    //因此进行网络通信势必有一个 socket 对象
    private DatagramSocket socket = null;
    //对于服务器来说,创建socket对象的同时,要给它绑定一个端口号
    //服务器是网络传输中,被动的一方,如果是操作系统的随机分配的端口,此时客户端就不知道这个端口是啥了,也就无法通信了
    public UdpEchoServer(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("启动服务器!");
        //服务器为多个客户端服务
        while(true){
            //只要有客户端,就可以提供服务
            //1.读取客户端发来的请求
            //receive 方法的参数是一个输出形参数,需要先构造好空白的DatagramPacket对象,交给receive进行填充
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);
            //此时这个 DatagramPacket 是一个特殊的对象,不方便直接进行处理,可以把这里包含的时刻拿出来构造成一个字符串.
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            //2.根据请求计算响应,此处是回显服务器,请求与响应相同
            String response = process(request);
            //3.把响应数据写回到客户端,send的参数也是 DatagramPacket,需要把这个对象构造好
            //此处的响应对象不能是空的字节数组构造的而是要响应数组构造
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //4.打印一下当前请求响应的处理中间结果
            System.out.printf("[%s:%d]req: %s; resp: %s\n",requestPacket.getAddress().toString(),
                    requestPacket.getPort(),request,response);
        }
    }
    //这个方法表示 根据请求计算响应
    public String process(String request){
        return request;
    }

    public static void main(String[] args) throws SocketException {
        //端口号码在 1024-65535 之间随机选择.
        UdpEchoServer server = new UdpEchoServer(9090);
        server.start();
    }
}
public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp = null;
    private int serverPort = 0;
    //一次通信需要有两个 ip 和两个端口
    //客户端的是 ip 127.0.0.1(环回 ip) 已知
    //客户端的端口号是系统随机分配的
    //服务器 ip 和端口号也要告诉客户端 , 才能顺利把消息发送给服务器.
    public UdpEchoClient(String serverIp , int serverPort) throws SocketException {
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    public void start() throws IOException {
        System.out.println("客户端启动!");
        Scanner scan = new Scanner(System.in);
        while(true){
            //1. 从控制台读取要发送的数据
            System.out.println(">");
            String request = scan.next();
            if(request.equals("exit")){
                System.out.println("good bye");
                break;
            }
            //2. 构成 Udp 请求并发送
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes() , request.getBytes().length,
                    InetAddress.getByName(serverIp) , serverPort);
            socket.send(requestPacket);
            //3. 读取服务器的 Udp 响应并解析.
            DatagramPacket respondPacket = new DatagramPacket(new byte[4096] , 4096);
            socket.receive(respondPacket);
            String respond = new String(respondPacket.getData() , 0 , respondPacket.getLength());
            //4. 把解析好的结果显示出来
            System.out.println(respond);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1",9090);
        client.start();
    }
}

 


Example 2: Look up dictionary server 

//对于UdpDictSever 主要代码与回显服务器一致
//主要是 "根据请求计算响应" 这个步骤不一样
public class UdpDictServer extends UdpEchoServer {
    private Map<String, String> dict = new HashMap<>();

    public UdpDictServer(int port) throws SocketException {
        super(port);
        // 给字典设置内容
        dict.put("cat", "小猫");
        dict.put("dog", "小狗");
        dict.put("pig", "小猪");
        dict.put("mouse", "老鼠");
        // 这里可以无限的设置

    }

    @Override
    public String process(String request) {
        //查词典和过程
        return dict.getOrDefault(request, "当前单词没有查到结果");
    }

    public static void main(String[] args) throws IOException {
        UdpDictServer server = new UdpDictServer(9090);
        server.start();
    }
}

 

 At this time, if the echo service is enabled again, it will cause a port conflict (one port can only be bound to one process).

Guess you like

Origin blog.csdn.net/liu_xuixui/article/details/128755350