2022Java learning notes 79 (network programming: TCP communication, TCP communication: multiple client messages [key points], tracking client online and offline functions, thread pool optimization)

Posted by RyanDev on Wed, 02 Mar 2022 14:04:39 +0100

2022Java learning notes 79 (network programming: TCP communication, TCP communication: multiple client messages [key points], tracking client online and offline functions, thread pool optimization)

1, TCP communication quick start

TCP protocol review:
1. TCP is a connection oriented, secure and reliable data transmission protocol
2. Before transmission, the "three-time handshake" mode is adopted for point-to-point communication, which is reliable
3. A large amount of data can be transmitted in the connection


Constructors and common API s

2, TCP client sends message

Sample code

package com.zcl.d12_tcpDaemo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

/*
    // Objective: to complete the client development of socket network programming entry case, with the function of one sending and one receiving
 */
public class ColientDemo {
    public static void main(String[] args) {
        System.out.println("-------- Client started successfully --------");
        try {
            // 1. Create socket communication pipeline to request the connection of the server 1
            /**
             * Parameter 1: IP address of the server
             * Parameter 2: server port
             */
            Socket socket = new Socket("127.0.0.1",7777);
            // 2. Get a byte output stream from the socket channel, which is responsible for sending data
            OutputStream ops = socket.getOutputStream();
            // Wrap the low-level byte stream into a print stream
            PrintStream ps = new PrintStream(ops);
            // send message
            ps.println("I invite you"); // It must be a one line message
            ps.flush();

            // Do not close the print stream. You need to send a close message to close it
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3, Server code writing


Sample code

package com.zcl.d12_tcpDaemo;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
    Objective: to develop the server of socket network programming entry code to receive messages
 */
public class ServerDemo {
    public static void main(String[] args) {
        System.out.println("-------- The server is started successfully --------");
        try {
            // 1. Registration server
            ServerSocket serverSocket = new ServerSocket(7777);
            // 2. The accept method must be called to wait for receiving the socket connection request from the client and establish the socket communication pipeline
            Socket socket = serverSocket.accept();
            // 3. Get a byte input from the socket communication pipeline
            InputStream is = socket.getInputStream();
            // 4. Convert the character input stream packet into a cached character input stream for message reception
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            // 5. Read messages by line according to cache byte input stream
            String msg;
            if ((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress()+"Said:"+msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

It is necessary to strictly abide by the principle of one sending and one receiving. If the client does not use one line of message to send, and the server uses to receive one line of data, an error will be reported, because the client does not send one line of data, and the server will receive incomplete messages
If the client sends only one line of data, and the server uses the loop while() to receive data, it will also report an error, because the client has completed a message sending, has been turned off, and the server is still receiving data

3, TCP communication: multiple sending and multiple receiving cases

On the basis of the above code, add repeated cycles to the client and server respectively

Client code modification

while (true) {
      System.out.println("Please enter the message to send:");
      String msg = sc.nextLine();
      // send message
      ps.println(msg); // It must be a one line message
      ps.flush(); // Refresh
}

Server code modification

while ((msg = br.readLine()) != null) {
     System.out.println(socket.getRemoteSocketAddress()+"Said:"+msg);
}

Now the written server can receive messages from one client at the same time. The reason is that the current server is single threaded and can only process messages from one client at a time

4, Receive multiple client messages at the same time [key]
Reference multithreading
Implementation code
1. Don't move the client code
2. Modify the code of the server

package com.zcl.d13_socket4;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/*
    Objective: to develop the server of socket network programming entry code to realize that the server can receive multiple client messages at the same time
 */
public class ServerDemo {
    public static void main(String[] args) {
        System.out.println("-------- The server is started successfully --------");
        try {
            // 1. Registration server
            ServerSocket serverSocket = new ServerSocket(7777);
            while (true) {
                // 2. After receiving a socket pipe from a client, an independent sub thread is responsible for reading the message
                Socket socket = serverSocket.accept();
                // 3. Start creating independent thread processing socket
                new ServerReaderThread(socket).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. Create a multi-threaded ServerReaderThread class to implement the Thread class

package com.zcl.d13_socket4;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            // 3. Get a byte input from the socket communication pipeline
            InputStream is = socket.getInputStream();
            // 4. Convert the character input stream packet into a cached character input stream for message reception
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            // 5. Read messages by line according to cache byte input stream
            String msg;
            while ((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress()+"Said:"+msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The client can receive more messages

About how to track the online and offline functions of the client

1. In the while loop of the server, you can know which client is online through the IP address of the socket
//Judge who is online on the system out. Println (socket. Getremotesocketaddress() + "he's online");
2. In the defined ServerReaderThread multithread class, the final IP address in the capture catch is judged as offline. If the client reports an error, the server will report an error to that client

// User offline notification
System.out.println(socket.getRemoteSocketAddress() + "He's offline");

In the defined ServerReaderThread multithread class

5, TCP communication: thread pool optimization
1. The client code does not need to be moved
2. Modify server code

package com.zcl.d14_scoket5;

import com.zcl.d13_socket4.ServerReaderThread;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/*
    Objective: to develop the server of socket network programming entry code to realize that the server can receive multiple client messages at the same time
 */
public class ServerDemo {
    // Use static variables to remember a thread pool object
    private static ExecutorService pool = new ThreadPoolExecutor(3,5,6,
            TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

    public static void main(String[] args) {
        System.out.println("-------- The server is started successfully --------");
        try {
            // 1. Registration server
            ServerSocket serverSocket = new ServerSocket(6666);
            while (true) {
                // 2. After receiving a socket pipe from a client, an independent sub thread is responsible for reading the message
                Socket socket = serverSocket.accept();
                // Judge who is online
                System.out.println(socket.getRemoteSocketAddress()+"He's online");
                // The task object is responsible for reading messages
                Runnable target = new ServerReaderRunnable(socket); // Submit route pool queue
                pool.execute(target);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

The ExecutorService thread pool object is added. The information initiated by the client is submitted through the thread pool and queued in the thread pool

3. Create a ServerReaderRunnable task object to implement the Runnable interface

The constructor needs to be rewritten to receive the object sent by the client

package com.zcl.d14_scoket5;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable{
    // Receiving object
    private Socket socket;
    // A parameterized constructor receives an object
    public ServerReaderRunnable(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            // 3. Get a byte input from the socket communication pipeline
            InputStream is = socket.getInputStream();
            // 4. Convert the character input stream packet into a cached character input stream for message reception
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            // 5. Read messages by line according to cache byte input stream
            String msg;
            while ((msg = br.readLine()) != null) {
                System.out.println(socket.getRemoteSocketAddress()+"Said:"+msg);
            }
        } catch (Exception e) {
            // e.printStackTrace();
            // User offline notification
            System.out.println(socket.getRemoteSocketAddress() + "He's offline");
        }
    }
}

What are the advantages of using thread pools
1. The server can reuse the thread pool to process multiple clients, which can avoid system paralysis
2. It is suitable for scenarios where the communication time of the client is short

Topics: Java