1. Bio Programming 1.1, traditional bio programming
The basic model of network programming is the C/S model, which is the communication between two processes.
The server provides IP and listening ports, the client through the connection operation to the server to listen to the address to initiate the connection request, through three handshake connection, if the connection is established successfully, the two sides can communicate through the socket.
In the traditional development of synchronous blocking model, ServerSocket is responsible for binding IP address, initiating the listening port, and the socket is responsible for initiating the connection operation. After the connection is successful, the two sides synchronize the blocking communication through the input and output streams.
Simply describe the server-side communication model of bio: The server with the Bio communication model, typically a separate acceptor thread that listens for client connections, after it receives a client connection request and creates a new thread for each client after the link processing is done The thread is destroyed by returning the reply to the client via the output stream. That is typical of a request one answer overnight model.
Traditional bio Communication Model diagram:
The biggest problem of the model is the lack of elastic scalability, when the client concurrent access increases, the number of threads on the server and the number of concurrent access to the client is proportional to 1:1, Java threads are relatively valuable system resources, the number of threads rapidly expanding, the performance of the system will fall sharply, with the continued increase in traffic , the system eventually dies--It's gone .
1.2. Pseudo asynchronous I/O programming
To improve this one-thread-join model, we can use a thread pool to manage these threads (refer to the previous article for more information), and implement 1 or more threads to handle the N-client model (but the underlying is still used for synchronous blocking I/O), often referred to as the pseudo-asynchronous I/O model.
Pseudo-Asynchronous I/O model diagram:
We know that if you use the Cachedthreadpool thread pool (without limiting the number of threads, refer to the article provided at the beginning of the text), in fact, in addition to automatically help us manage threads (multiplexing), it will look like a 1:1 client: Thread number model, Using Fixedthreadpool, we can effectively control the maximum number of threads, ensure the control of the limited resources of the system, and realize the pseudo-asynchronous I/O model of n:m.
However, because the number of threads is limited, if a large number of concurrent requests occur, more than the maximum number of threads can wait until there are idle threads in the thread pool to be reused. When the input stream to the socket is read, it blocks until it occurs:
- have data to read
- Available data and read complete
- A null pointer or I/O exception occurred
So when reading data is slow (such as large data volume, network transmission slow, etc.), a large number of concurrent situations, other access to the message, can only wait, this is the biggest disadvantage.
NIO, which is about to be introduced later, can solve this problem.
2. NIO Programming
The java.nio.* package in JDK 1.4 introduces a new Java I/O library, which is designed to increase speed. In fact, "old" I/O packages have been re-implemented using NIO, which can benefit even if we don't explicitly use NIO programming. The increase in speed can occur in both file I/O and network I/O, but this article discusses only the latter.
2.1. Introduction
NiO we generally think of new I/O (also officially called), because it is new to the old I/O class library (actually introduced in JDK 1.4, but this term will continue to last for a long time, even if they are now appear to be "old", so also prompted us to name, Need to think about it) and made a big change. But folk with many people called Non-block I/O, that is, non-blocking I/O, because this is called, more can reflect its characteristics. In the following, NiO does not refer to the entire new I/O library, but non-blocking I/O.
NIO provides two different socket channel implementations for Socketchannel and Serversocketchannel that correspond to sockets and serversocket in the traditional bio model.
The new two channels support both blocking and non-blocking modes.
Blocking mode use is as simple as traditional support, but not performance and reliability, and non-blocking mode is just the opposite.
For low-load, low-concurrency applications, you can use synchronous blocking I/O to improve development rates and better maintainability, and for high-load, high-concurrency (network) applications, you should use NIO's nonblocking mode for development.
The basics are described in the following first.
2.2. Buffer buffers
Buffer is an object that contains some data to be written or read.
In the NIO library, all data is processed in a buffer. When the data is read, it is read directly into the buffer, and is written to the buffer when the data is written. Accessing data in NiO at any time is done through a buffer.
The buffer is actually an array and provides information about the data structure access and the maintenance of the read-write location.
Specific buffers have these: Bytebuffe, Charbuffer, Shortbuffer, Intbuffer, Longbuffer, Floatbuffer, DoubleBuffer. They implement the same interface: Buffer.
2.3. Channel Channels
We read and write to the data through the channel, it is like a water pipe, is a channel. The channel differs from the flow where the channel is bidirectional and can be used for read, write, and simultaneous reading and writing operations.
The channels of the underlying operating system are generally full-duplex, so full-duplex channel streams can better map the underlying operating system's APIs.
There are two major types of channel:
- Selectablechannel: User network read/write
- FileChannel: For file operations
The Serversocketchannel and socketchannel that are involved in the following code are subclasses of Selectablechannel.
2.4. Multiplexer Selector
Selector is the basis for Java NIO programming.
Selector provides the ability to choose a task that is already in place: Selector constantly polls the channel on which it is registered, and if a channel reads or writes on it, the channel is in a ready state and is selector polled. The Selectionkey can then be used to obtain a set of ready channel for subsequent I/O operations.
A selector can poll multiple channel at the same time, because the JDK uses epoll () instead of the traditional select implementation, so there is no limit of the maximum connection handle 1024/2048. Therefore, only one thread is responsible for selector polling, which can be accessed by thousands of clients.
2.5. NiO Service Side 2, NIO programming
The java.nio.* package in JDK 1.4 introduces a new Java I/O library, which is designed to increase speed. In fact, "old" I/O packages have been re-implemented using NIO, which can benefit even if we don't explicitly use NIO programming. The increase in speed can occur in both file I/O and network I/O, but this article discusses only the latter.
2.1. Introduction
NiO we generally think of new I/O (also officially called), because it is new to the old I/O class library (actually introduced in JDK 1.4, but this term will continue to last for a long time, even if they are now appear to be "old", so also prompted us to name, Need to think about it) and made a big change. But folk with many people called Non-block I/O, that is, non-blocking I/O, because this is called, more can reflect its characteristics. In the following, NiO does not refer to the entire new I/O library, but non-blocking I/O.
NIO provides two different socket channel implementations for Socketchannel and Serversocketchannel that correspond to sockets and serversocket in the traditional bio model.
The new two channels support both blocking and non-blocking modes.
Blocking mode use is as simple as traditional support, but not performance and reliability, and non-blocking mode is just the opposite.
For low-load, low-concurrency applications, you can use synchronous blocking I/O to improve development rates and better maintainability, and for high-load, high-concurrency (network) applications, you should use NIO's nonblocking mode for development.
The basics are described in the following first.
2.2. Buffer buffers
Buffer is an object that contains some data to be written or read.
In the NIO library, all data is processed in a buffer. When the data is read, it is read directly into the buffer, and is written to the buffer when the data is written. Accessing data in NiO at any time is done through a buffer.
The buffer is actually an array and provides information about the data structure access and the maintenance of the read-write location.
Specific buffers have these: Bytebuffe, Charbuffer, Shortbuffer, Intbuffer, Longbuffer, Floatbuffer, DoubleBuffer. They implement the same interface: Buffer.
2.3. Channel Channels
We read and write to the data through the channel, it is like a water pipe, is a channel. The channel differs from the flow where the channel is bidirectional and can be used for read, write, and simultaneous reading and writing operations.
The channels of the underlying operating system are generally full-duplex, so full-duplex channel streams can better map the underlying operating system's APIs.
There are two major types of channel:
- Selectablechannel: User network read/write
- FileChannel: For file operations
The Serversocketchannel and socketchannel that are involved in the following code are subclasses of Selectablechannel.
2.4. Multiplexer Selector
Selector is the basis for Java NIO programming.
Selector provides the ability to choose a task that is already in place: Selector constantly polls the channel on which it is registered, and if a channel reads or writes on it, the channel is in a ready state and is selector polled. The Selectionkey can then be used to obtain a set of ready channel for subsequent I/O operations.
A selector can poll multiple channel at the same time, because the JDK uses epoll () instead of the traditional select implementation, so there is no limit of the maximum connection handle 1024/2048. Therefore, only one thread is responsible for selector polling, which can be accessed by thousands of clients.
2.5. NiO Service End
The main steps to create a NIO server are as follows:
- Open Serversocketchannel, listen for client connections
- Binding listening port, setting the connection to non-blocking mode
- Create a reactor thread, create a multiplexer, and start a thread
- Register the Serversocketchannel with the selector on the reactor thread to listen for the Accept event
- Selector polling for the ready key
- Selector listens to new client access, processes new access requests, completes TCP three handshake, resumes physical link
- Setting the client link to non-blocking mode
- Registers the newly accessed client connection to the selector of the reactor thread, listens for read operations, reads the network messages sent by the client
- Asynchronously reads a client message to a buffer
- Decodes a buffer, processes a half-packet message, encapsulates a successful message into a task
- Encodes the reply message to buffer, calling Socketchannel's write to send the message asynchronously to the client
Because the reply message sends, the Socketchannel is also asynchronous non-blocking, therefore cannot guarantee once to send the data to send the complete, at this time will appear to write half packet of problem. We need to register the write operation, constantly polling the selector will not send the finished message sent complete, and then through the buffer Hasremain () method to determine whether the message is sent.
3. AIO Programming
NIO 2.0 introduces the concept of a new asynchronous channel and provides an implementation of asynchronous file channels and asynchronous socket channels.
Asynchronous socket channels are true asynchronous non-blocking I/O, corresponding to event-driven I/O (AIO) in UNIX network programming. He doesn't need too many selector to poll a registered channel for asynchronous read and write, simplifying the NIO programming model.
4. Comparison of various I/O
Let's look at a table to compare it visually:
The specific choice of what model or NIO framework, completely based on the actual application scenarios and performance requirements of the business, if the client is very few, the server load is not heavy, there is no need to choose to develop relatively less simple nio to do the service side, instead, should consider the use of NIO or related frameworks.
5. Complete instance Code
Java Network IO Programming Summary (BIO, NIO, AIO all with full instance code)