Netty core technology 2–BIO programming

1. I/O model

  1. A simple understanding of the I/O model: what kind of channel is used to send and receive data, determines the performance of program communication to a large extent

  2. Java supports 3 network programming models/IO modes: BIO, NIO, AIO

  3. Java BIO: Synchronize and block (traditional blocking type), the server implementation mode is one thread per connection, that is, when the client has a connection request, the server The end needs to start a thread for processing, If this connection does not do anything, it will cause unnecessary thread overhead

    image-20230512165651728

  4. Java NIO: synchronous non-blocking, the server implementation mode is one thread handles multiple requests (connections), that is, the client sends The connection request will be registered to the multiplexer, and the multiplexer polling will process the I/O request when there is a connection

    image-20230512165853634

  5. Java AIO(NIO.2) : Asynchronous non-blocking, AIO introduces the concept of Asynchronous channel, adopts Proactor mode, which simplifies programming, A valid request will start the thread. Its characteristic is that the operating system will notify the server after the completion of the thread. It is generally suitable for applications with a large number of connections and a long connection time

2. BIO, NIO, AIO applicable scenario analysis

  1. The BIO method is suitable for architectures where the number of connections is relatively small and fixed. This method has relatively high requirements on server resources, and concurrency is limited to applications. The only choice before JDK1.4 , but the program is simple and easy to understand.
  2. The NIO method is suitable for architectures with a large number of connections and relatively short connections (light operation), such as chat server, bullet screen system, inter-server communication etc. Programming is more complicated, JDK1.4 starts to support.
  3. The AIO method is used in architectures with a large number of connections and long connections (heavy operations), such as Album Server, which fully calls the OS to participate in concurrent operations, and the programming is more complicated. JDK7 starts to support .

3. Basic introduction to JAVA BIO

  1. Java BIO is traditional java io programming, and its related classes and interfaces are in java.io
  2. BIO(blocking I/O): Synchronous blocking, the server implementation mode is one thread per connection, that is, when the client has a connection request, the server needs to start a thread for processing , if this connection does not do anything, it will cause unnecessary thread overhead. It can be improved through the thread pool mechanism (realize multiple clients connecting to the server).
  3. The BIO method is suitable for the architecture with a relatively small and fixed number of connections. This method has relatively high requirements on server resources, and concurrency is limited to applications. It is the only choice before JDK1.4, and the program is simple and easy to understand

4. JAVA BIO working mechanism

4.1 Working principle diagram

image-20230512170932098

4.2 Simple process of BIO programming

  1. The server starts a ServerSocket
  2. The client starts Socket to communicate with the server. By default, the server needs to establish a thread for each client to communicate with it.
  3. After the client sends a request, it first consults the server whether there is a thread response, if not, it will wait or be rejected
  4. If there is a response, the client thread will wait for the end of the request before continuing

5. Java BIO application examples & amp;telnet basic usage

Example description:

  1. Use the BIO model to write a server, listen to port 6666, and start a thread to communicate with it when a client connects.
  2. It is required to use the thread pool mechanism to improve, and multiple clients can be connected.
  3. The server can receive the data sent by the client (telnet method is enough).
package site.zhouui.nioAndNetty.bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BIOSServer {<!-- -->
    public static void main(String[] args) throws IOException {<!-- -->
        //Thread pool mechanism

        //idea
        //1. Create a thread pool
        //2. If there is a client connection, create a thread and communicate with it (write a separate method)
        ExecutorService newCachedThreadPool = Executors. newCachedThreadPool();
        //Create ServerSocket
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("Server started");

        while (true){<!-- -->
            System.out.println("thread information id=" + Thread.currentThread().getId() + "name=" + Thread.currentThread().getName());
            System.out.println("Waiting for connection...");
            Socket socket = serverSocket. accept();
            System.out.println("Connect to a client");
            //Create a thread and communicate with it (write a separate method)
            newCachedThreadPool.execute(()->{<!-- --> //we rewrite
                //Can communicate with client
                handle(socket);
            });



        }
    }

    private static void handle(Socket socket) {<!-- -->
        try {<!-- -->
            System.out.println("thread information id=" + Thread.currentThread().getId() + "name=" + Thread.currentThread().getName());
            System.out.println("read....");
            byte[] bytes = new byte[1024];
            InputStream inputStream = socket. getInputStream();
            while (true){<!-- -->
                int read = inputStream. read(bytes);
                if (read!=-1){<!-- -->
                    System.out.println(new String(bytes,0,read)); //output the data sent by the client
                } else {<!-- -->
                    break;
                }
            }
        }catch (Exception e){<!-- -->
            e.printStackTrace();
        }finally {<!-- -->
            System.out.println("Close the connection with client");
            try {<!-- -->
                socket. close();
            } catch (IOException e) {<!-- -->
                e.printStackTrace();
            }
        }

    }
}
  1. start server

    The server waits for the client to connect

    image-20230514101416436

  2. Use cmd to connect to the server

    telnet 127.0.0.1 6666
    

    image-20230512181847420

  3. After the first step, the following page appears after pressing Enter

    image-20230512181932809

    The server log shows that it is connected to a client, and a thread with a thread id of 20 is started to block and wait for the client to send information, and then the thread with an id of 1 (main thread) blocks again and waits for a new client connection

    image-20230514101234705

  4. Use the shortcut key: CTRL + ] to display the welcome page

    image-20230512182019468

  5. Input ? to output help document

    image-20230512182212801

  6. Use the send command to send a string to the server

    image-20230512182439517

  7. cmd connects to a client again, the thread with id 1 (the main thread) blocks again a thread with id 20 waiting for the client to send information, and then the thread with id 1 blocks again waiting for a new client connection

    image-20230514101853945

6. BIO problem analysis – summary

  1. Each request needs to create an independent thread to perform data Read, business processing, and data Write with the corresponding client.
  2. When the number of concurrency is large, a large number of threads need to be created to handle connections, and the system resource usage is large.
  3. After the connection is established, if the current thread has no data to read temporarily, the thread will be blocked on the Read operation, resulting in a waste of thread resources