Principle analysis and code implementation of NIO

Source: Internet
Author: User

IO commonality: Each thread's processing process is probably read data, decoding, calculation processing, encoding, sending response.

The standard IO is based on byte stream and character stream,

NIO is a channel-and buffer-based operation, and the data isalways read from the channel to the buffer or written to the channel from the buffer.

Java NiO channels are similar to streams, but are somewhat different:

The data can be read from the channel, and the data can be written to the channel. But stream reads and writes are usually one-way.

Channels can be read and written asynchronously.

The data in the channel is always read to a buffer first, or it is always written from a buffer .

When a thread reads data from a channel into a buffer, the thread can still do something else. When the data is written to the buffer, the thread can continue to process it. Writing a channel from a buffer is similar.

A The difference between Java NIO and blocking I/O

1. Blocking I/O communication model

Blocking I/O is blocked when calling the Inputstream.read () method, and it waits until the data arrives (or times out) to return;

When the serversocket.accept () method is called, it also blocks until a client connection is returned, and after each client connects, the server initiates a thread to process the client's request.

Disadvantages:

1. When the client is a long time, a large number of processing threads are created. And each thread consumes stack space and some CPU time

2. Blocking can lead to frequent context switching, and most context switches may be meaningless.

2. Java NIO principle and communication model

1. all IO events are handled by a dedicated thread and are responsible for distribution.

2. Event-driven: events are triggered when they arrive, rather than synchronized to monitor events.

3. thread Communication: The threads communicate through wait,notify and other means. Ensure that each context switch is meaningful. Reduce unnecessary thread switching.

Principle:

The server and the client each maintain a management channel object that we call selector (the object that manages the channel)

-- The object can detect events on one or more channels (channel) .

Two Java NIO Server and client code implementations

Server-side:

1, get an Serversocket channel (Build a road)

Serversocketchannel Serverchannel = Serversocketchannel.open ();

2, set the channel to non-blocking (set this road is two-way driving, no traffic jam)

Serverchannel.configureblocking (False)

3. bind the ServerSocket of the channel to the port 9000 (9000 lot at the end of the Road Village Gate )

ServerChannel.socket.bind (new inetsocketaddress (9000)// Create socket address );

4, get a channel manager (Hire a gatekeeper)

Selector Selector = Selector.open ();

5, bind the channel Manager and channel, and register the Selectionkey.op_accept event with the channel manager ( Village Gate Road, we find a person on the road sentry, to this person arranged a task (event), When we find a red-fisted car passing by, let us know if it doesn't matter. )

Serverchannel.register (selector,selectionkey.op_accept);

6, began to carry out the task (the man began to work, if there is a red car, just leave.) )

when the event arrives,Selector.select () returns (reports)and blocks if the event does not reach selector.select () . (kept there)

Selector.select ();

7. when completing a task, get an iterator for the item selected in selector (meaning a collection of multiple tasks)

Iterator ite = Selector.selectedkeys (). Iterator (); //

8, iterate through the collection. Access (the name of the Road we build)

Serversocketchannel Server = (Serversocketchannel) key.channel (); // get the channel that created this key

9, access to the customer service connection channel (this car from the road)

Socketchannel channel = Server.accept ();

set the client side channel to non-blocking

Channel.configureblocking (FALSE);

Oneby one, through the channel to the customer service side to send information (according to the car to the road , we drive to see )

Channel.write (Bytebuffer.wrap (New sttring (" message Content "). GetBytes ());

After the successful connection with the client, in order to receive the client's information, you need to set the Read permission to the channel.

Channel.register (This.selector, Selectionkey.op_read);

Package Nio;import Java.io.ioexception;import Java.net.inetsocketaddress;import java.nio.bytebuffer;import Java.nio.channels.selectionkey;import Java.nio.channels.selector;import Java.nio.channels.ServerSocketChannel; Import Java.nio.channels.socketchannel;import java.util.iterator;/** * NiO server * @author Xiao Liu */public class nioserver {//Channel Manager Private Selector selector;/** * Get a serversocket channel and do some initialization work on the channel * @param port * Bound Port number * @throws Ioexcepti On */public void initserver (int port) throws IOException {//Get a serversocket channel serversocketchannel Serverchannel = Server Socketchannel.open ();//Set the channel to non-blocking serverchannel.configureblocking (false);// Bind the ServerSocket of the channel to Port Serverchannel.socket (). bind (New Inetsocketaddress (port));//Get a channel manager This.selector = Selector.open ();//binds the channel manager and the channel, registers the Selectionkey.op_accept event for that channel, registers the event, and//When the event arrives, Selector.select () returns, If the event does not reach Selector.select () it will remain blocked. Serverchannel.register (selector, selectionkey.op_accept);} /** * Polling is used to monitor whether there are events on the selector that need to be handled, and if so,Then process * @throws IOException */@SuppressWarnings ("unchecked") public void Listen () throws IOException {System.out.println ("Server started successfully!") ");//Polling Access Selectorwhile (true) {//When the registered event arrives, the method returns; otherwise, the method will always block Selector.select ();//Get an iterator for the selected item in selector. The selected item is the registered event iterator ite = This.selector.selectedKeys (). iterator (); while (Ite.hasnext ()) {Selectionkey key = ( Selectionkey) Ite.next ();//delete the selected key in case of repeated processing ite.remove ();//Client Request Connection event if (key.isacceptable ()) {Serversocketchannel Server = (Serversocketchannel) key.channel ();//obtain and client-connected channels Socketchannel Channel = Server.accept ();// Set to non-blocking channel.configureblocking (false);//Here you can send a message to the client Oh Channel.write (Bytebuffer.wrap ("Send a message to the client"). GetBytes ()));//After the connection with the client is successful, you need to set read permissions to the channel in order to receive the client's information. Channel.register (This.selector, selectionkey.op_read);//obtained a readable event} else if (Key.isreadable ()) {read (key);}}} /** * Handles events that read messages sent by clients * @param key * @throws ioexception */public void Read (Selectionkey key) throws IOException {//server can Read message: Gets the event that occurs when the socket channel Socketchannel channel = (SockEtchannel) Key.channel ();//create buffer for read Bytebuffer buffer = bytebuffer.allocate; channel.read (buffer); byte[] data = Buffer.array (); String msg = new string (data). Trim (); SYSTEM.OUT.PRINTLN ("Server received message:" + msg); Bytebuffer Outbuffer = Bytebuffer.wrap (Msg.getbytes ()); Channel.write (outbuffer);//Send message back to client}/** * Start service-side test * @throws IOException */public static void Main (string[] args) throws IOException {nioserver Server = new Nioserver (); server.initser ver (8000); Server.listen ();}}

The customer service side and the server are basically the same, here is not detailed analysis. Look directly at the code

/** * NIO Client * * @author Xiao Liu */public class nioclient {//Channel manager Private Selector selector;/** * Get a socket channel and do some initialization work on the channel * * @param IP * IP * port number of the server to which the connection is @param port * @throws ioexception */public void Initclien T (String IP, int port) throws IOException {//Get a socket channel Socketchannel channel = Socketchannel.open ();//Set channel to non-blocking channels . configureblocking (false);//obtain a channel manager This.selector = Selector.open ();//Client Connection server, in fact, the method execution does not implement the connection, need to be in the Listen () method to tune// Use Channel.finishconnect () to complete the connection Channel.connect (new Inetsocketaddress (IP, port));//Bind the channel manager to the channel, and register the Selectionkey.op_connect event for the channel. Channel.register (selector, selectionkey.op_connect);} /** * Polling is used to monitor whether there are events on the selector that need to be handled, and if so, to process * * @throws IOException */@SuppressWarnings ("unchecked") public void Listen () throws IOException {//Polling access Selectorwhile (true) {selector.select ();//iterator selector for the selected item iterator ITE = This.selector . Selectedkeys (). iterator (); while (Ite.hasnext ()) {Selectionkey key = (Selectionkey) ite.next ();//deleteIn addition to the selected key, in case of repeated processing ite.remove ();//Connection event occurs if (Key.isconnectable ()) {Socketchannel channel = (Socketchannel) key.channel (); /If you are connecting, complete the connection if (channel.isconnectionpending ()) {Channel.finishconnect ();} Set to non-blocking channel.configureblocking (false);//Here you can send a message to the server Oh Channel.write (bytebuffer.wrap ("Send a message to the server") ). GetBytes ());//After the connection with the server is successful, you need to set read permissions to the channel in order to receive the information from the server. Channel.register (This.selector, selectionkey.op_read);//obtained a readable event} else if (Key.isreadable ()) {read (key);}}} /** * Handling events that read information sent from the service side * * @param key * @throws ioexception */public void Read (Selectionkey key) throws IOException {//and The Read method on the server side is the same as Socketchannel channel = (Socketchannel) key.channel (); Bytebuffer buffer = bytebuffer.allocate, channel.read (buffer); byte[] data = Buffer.array (); String msg = new string (data). Trim (); SYSTEM.OUT.PRINTLN ("Message received by the client:" +msg); Bytebuffer Outbuffer = Bytebuffer.wrap (Msg.getbytes ()); Channel.write (Outbuffer);} /** * Start Client Test * * @throws ioexception */public static void Main (string[] args) throws Ioexception {nioclient client = new Nioclient () client.initclient ("localhost", 8000); Client.listen ();}} 

Summary: The main Clear Channel manager, write cache, read cache.

Principle analysis and code implementation of NIO

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.