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.