A preface

With the deepening of learning, Le Le gradually can better understand and learn through the code at the same time to query some information

Comparative advantages of two IO models

The most obvious advantage of NIO is the traditional BIO. A server socket is directly connected to a client socket, and the server needs to create a new thread for each client to handle the communication between the client, which inevitably costs a lot of resources on the server.

Our NIO can access tens of thousands or more client connections with only one selector and one polling thread, which is the biggest improvement and change from BIO. The second is the way to establish the connection. In traditional BIO, the client server establishes the TCP connection through the three-way handshake, while in NIO, the client directly registers the channel with the server multiplexer, and then the server polls, which reduces the overhead of the three-way handshake request response. Again is the direct buffer code stream, traditional bio request and response data is read by side to create the output stream directly to the other end of the output, while the other DianChuan write data input stream, it is depend on the network, if the network is bad can lead to do so time is not closed, resulting in resource waste and a cause increased costs. Nio introduced the buffer to write data and write data directly to the buffer, so it doesn’t depend on the network. One end can write data to the buffer and then close the write stream, so you just need to tell the other end to read. The other end turns on the read stream and quickly reads the buffer’s data, which can then be quickly closed. If the network is not good, it will not spend resources on the other side.

Iii Code Practice

  1. BIO
  • The service side

       try {
           serverSocket = new ServerSocket();
           serverSocket.bind(new InetSocketAddress(7397));
           System.out.println("itstack-demo-netty bio server start done.");
           while (true) {
               Socket socket = serverSocket.accept();
               BioServerHandler handler = new BioServerHandler(socket, Charset.forName("GBK"));
               handler.start();
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
    Copy the code
  • The client

    Try {Socket Socket = new Socket("127.0.0.1", 7397); System.out.println("itstack-demo-netty bio client start done."); BioClientHandler bioClientHandler = new BioClientHandler(socket, Charset.forName("utf-8")); bioClientHandler.start(); } catch (IOException e) { e.printStackTrace(); }Copy the code

From the point of view of the code is very simple, one-to-one direct connection, first create in the binding and accept three steps, but multiple connections to open multiple threads

2.NIO

  • The service side

    Try {// open selector = selector. Open (); SocketChannel = serverSocketChannel.open (); / / set the channel to a non-blocking socketChannel. ConfigureBlocking (false); Socketchannel.socket ().bind(new InetSocketAddress(port), 1024); // Register the server channel with the multiplexer and listen for the blocking event socketChannel.register(selector, selectionkey.op_accept); System.out.println("itstack-demo-netty nio server start done."); new NioServerHandler(selector, Charset.forName("GBK")).start(); } catch (IOException e) { e.printStackTrace(); }Copy the code
  • The client

       Selector selector = Selector.open();
       SocketChannel socketChannel = SocketChannel.open();
       socketChannel.configureBlocking(false);
    
       boolean isConnect = socketChannel.connect(new InetSocketAddress("192.168.1.116", 7397));
       if (isConnect) {
           socketChannel.register(selector, SelectionKey.OP_READ);
       } else {
           socketChannel.register(selector, SelectionKey.OP_CONNECT);
       }
       System.out.println("itstack-demo-netty nio client start done. ");
       new NioClientHandler(selector, Charset.forName("GBK")).start();
       
    Copy the code

    Now it’s easier to understand. The BIO used to be directly connected. Now NIO comes up with an intermediate layer, which is kind of like a cloud disk, where you upload all the data that the server needs to upload. You don’t have to wait until there’s a connection.

3.AIO

  • The service side

        try {
          serverSocketChannel = AsynchronousServerSocketChannel.open(AsynchronousChannelGroup.withCachedThreadPool(Executors.newCachedThreadPool(), 10));
          serverSocketChannel.bind(new InetSocketAddress(7397));
          System.out.println("itstack-demo-netty aio server start done. ");
          // 等待
          CountDownLatch latch = new CountDownLatch(1);
          serverSocketChannel.accept(this, new AioServerChannelInitializer());
          latch.await();
      } catch (Exception e) {
          e.printStackTrace();
      }
      
    Copy the code

    We’ll start with the CountDownLatch class. This class is a counter that controls when multiple threads access a resource. Its function is that it has to wait until everything else is thought to be finished before it can execute the resource below it, so it initializes itself as 1 and then it waits to execute the “await” resource before it can execute the next one.

  • The client

    AsynchronousSocketChannel socketChannel = AsynchronousSocketChannel.open(); Future<Void> Future = Socketchannel.connect (new InetSocketAddress("127.0.0.1", 7397)); System.out.println("itstack-demo-netty aio client start done."); future.get(); socketChannel.read(ByteBuffer.allocate(1024), null, new AioClientHandler(socketChannel, Charset.forName("GBK"))); Thread.sleep(100000);Copy the code

    The client uses the Future, which is non-blocking, so it can perform the following functions without waiting for the result to return, but if I want to return the result, I have to call future.get(), which will return the result. This class is quite unique and can be different. AIO is asynchronous non-blocking, and its non-blocking is embodied in the Future.