Q: BIO can’t overcome long connections, so what modes can support long connections?

Slow down: Here’s the NIO model, synchronous non-blocking. Whenever we go to the canteen to order food, we have to wait in line for the chef to take the food. During this process, we had to wait in this line without going to the bathroom or sitting down. This is analogous to the BIO model, where once a connection is established, a thread is required to process it until the connection is completed, and that thread is occupied during the entire process.

So someone came up with an idea: when we place an order, we are given an order number and a screen shows which order has been completed. As a result, we are completely liberated to do other things, and we can even pick up our food later (after finishing what we are doing) without having to wait in line.

NIO’s idea is to keep track of new connections through a container, and then we loop through the container to listen for connections, and when data comes back, we let a thread handle it. (Exit the thread of execution when it is finished, but it is not yet disconnected.)


Q: Can you give an example in code?

Slowly: Ok, let’s simulate the NIO process through NetTY.

The service side

public class NIOServer extends Thread {
    
    LinkedList<SocketChannel> clients = new LinkedList<>();  // The container that holds the connection
    
    public static void main(Stringp[] args) throw IOException {
        NIOSocket socket = new NIOSocket();
        
        ServerSocketChannel ss = ServerSocketChannel.open();  // Enable the listener to receive the client
        ss.bind(new InetSocketAddress(8080)); // Listen on port 8080
        ss.configureBlocking(false);   // Set non-blocking mode, meaning that each connection does not hold threads all the time
        socket.start();  // Start the thread and let it loop to see if it has received the data sent by the connection
         
        while (true) {
            // Receive the client connection
            SocketChannel client = ss.accept();  // The phase is not blocked, and null is returned if there is no connection
            if(client ! =null) {
                client.configureBlocking(false);  // Make the client connection non-blocking as well
                clients.add(client);  // Put the connection into the container}}}@Override
    public void run(a) {
        ByteBuffer buffer = ByteBuffer.allocateDirect(4096);   // Set the read buffer
        int i = 0;
        while (true) {
            if (i == clients.size())
                i = 0;
            SocketChannel c = clients.get(i++);
            try {
                int num = c.read(buffer);   // -1: not written, 0: disconnected, n: written
                if (num > 0) {
                    buffer.flip();
                    byte[] aaa = new byte[buffer.limit()];
                    buffer.get(aaa);
                    String b = new String(aaa);
                    System.out.println(c.socket().getPort() + ":" + b);
                    buffer.clear();
                } else if (num == 0) {  // The connection is downc.close(); clients.remove(c); }}catch(IOException e) { e.printStackTrace(); }}}}Copy the code

Client connection

public class NIOClient {
    public static void main(String[] args) throw IOException {
        SocketChannel sc = SocketChannel.open();  // Open the client connection
        sc.connect(new InetSocketAddress("localhost".8080));  // Set the server address
        System.out.println("Waiting to receive data"); }}Copy the code


Q: How is NIO better than BIO?

The biggest advantage of NIO is that it does not allow a connection to be thread-exclusive. By marking each connection, it gives it threads when it needs them and frees them when it doesn’t. And because of the token, it supports a long connection mode, which does not require a triple handshake connection each time data is sent.