Project team is to do IM products, the server is of course using NIO technology to do the communication bottom. However, there has been some theoretical understanding of NIO, no practice, the recent free, the practice of the next NiO.
NIO, new Io, also known as non-blocking IO. Non-blocking is one of the most important differences between it and traditional IO. Traditional IO uses sockets for communication, and NIO uses channel for message interaction. The channel must be registered on the selector to tell selector of the events it is interested in. This is an implementation of the Observer pattern . Can describe the relationship between channel and selector, channel is train track, selector is train control room. Multiple channel can be registered on the same selector, and the channel is dispatched on one thread. However, traditional IO needs to create a thread for each socket. This is one of the advantages of NIO and does not require too many threads.
Service-side code for the NIO version:
Package Cn.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;public class Nioserver {private Selectorserverselector;public nioserver initserver (int port) throws IOException {Serversocketchannel ServerChannel = Serversocketchannel.open ();//non-blocking mode serverchannel.configureblocking (false);//Bind port number Serverchannel.socket (). Bind ( New Inetsocketaddress (port)); this.serverselector = Selector.open (); Serverchannel.register (Serverselector, selectionkey.op_accept); return this;} public void Startlistening () throws IOException {System.out.println ("Server started successfully! "); while (true) {//When the registered event arrives, the method returns; otherwise, the method will always block Serverselector.select ();iterator<selectionkey> Iterator = This.serverSelector.selectedKeys (). iterator (); while (Iterator.hasnext ()) {Selectionkey key = (Selectionkey) Iterator.next ();// Must be deleted, otherwise the old Keyiterator.remove () will be traversed on the next traversal, if (key.isacceptable ()) {Accept (key),} else if (Key.isreadable ()) {Read (key)}}} Accept client connection request private void accept (Selectionkey key) throws IOException {Serversocketchannel Server = (serversocketchannel Key.channel ();//obtain and client-connected channels Socketchannel Channel = Server.accept ();//set to non-blocking channel.configureblocking (false); Channel.write (Bytebuffer.wrap ("Client connection succeeded \ n"). GetBytes ());//Registered Channel.register (This.serverselector, Selectionkey.op_read);} private void Read (Selectionkey key) {try {Socketchannel channel = (Socketchannel) key.channel ();//create read buffer Bytebuffer buf fer = Bytebuffer.allocate (1024x768); channel.read (buffer); String msg = new String (Buffer.array ()). Trim (); SYSTEM.OUT.PRINTLN ("Service side:" + msg);} catch (Exception e) {e.printstacktrace ();}} public static void Main (string[] args) throws IOException {new Nioserver (). Initserver (8080). Startlistening ();}}Client code for the NIO version:
Package Cn.nio;import Java.io.ioexception;import Java.net.inetsocketaddress;import java.nio.bytebuffer;import Java.nio.channels.closedchannelexception;import Java.nio.channels.selectionkey;import Java.nio.channels.Selector ; Import Java.nio.channels.socketchannel;import Java.util.iterator;public class Nioclient {private selectorselector; Public nioclient initclient (String IP, int port) throws IOException {Socketchannel channel = Socketchannel.open ();//non-blocking CH Annel.configureblocking (false); this.selector = Selector.open ();//comment for the Connect method: This method returns false and must be called later by calling the The Finishconnect method to complete the connection operation. Boolean result = Channel.connect (new inetsocketaddress (IP, port)); SYSTEM.OUT.PRINTLN (result); Return false//Register Channel.register (selector, selectionkey.op_connect); return this;} public void Startlistening () throws IOException {while (true) {Selector.select ();iterator<selectionkey> Iterator = This.selector.selectedKeys (). iterator (); while (Iterator.hasnext ()) {Selectionkey key = (Selectionkey) iterator.next ();Must be removed, otherwise the old Keyiterator.remove () will be traversed on the next traversal, if (key.isconnectable ()) {Connect (key);} else if (Key.isreadable ()) {Read ( key);}}} private void Connect (Selectionkey key) throws IOException, closedchannelexception {socketchannel channel = ( Socketchannel) Key.channel ();//If you are connecting, complete the connection if (channel.isconnectionpending ()) {Channel.finishconnect ();} Channel.configureblocking (false); Channel.write (Bytebuffer.wrap (New String ("Client connection succeeded"). GetBytes ());// Registered Channel.register (This.selector, selectionkey.op_read);} private void Read (Selectionkey key) throws IOException {//server readable message: The socket channel that gets the event occurred socketchannel channel = ( Socketchannel) Key.channel ();//create buffer for read Bytebuffer buffer = bytebuffer.allocate (1024x768); channel.read (buffer); String msg = new String (Buffer.array ()). Trim (); SYSTEM.OUT.PRINTLN ("Client received message:" + msg);} /** * Start Client Test * * @throws ioexception */public static void Main (string[] args) throws IOException {new Nioclient (). INITCL Ient ("localhost", 8080). Startlistening ();}}
Considering that other languages do not necessarily have NIO technology, our clients are C + +. Is it possible for a NIO server to communicate with a non-NIO client? Do a traditional IO client, do the testing. Feasible!
Package Cn.nio;import Java.io.bufferedreader;import Java.io.ioexception;import java.io.inputstreamreader;import Java.io.printwriter;import Java.net.socket;public class Normalclient {socketclientsocket= null;public NormalClient Initclient (String IP, int port) {try {clientsocket = new Socket (IP, port),} catch (IOException e) {e.printstacktrace ();} return this;} public void Read () throws IOException {PrintWriter pw = new PrintWriter ((Clientsocket.getoutputstream ())); BufferedReader br = new BufferedReader (New InputStreamReader (Clientsocket.getinputstream ())); String line = Null;while (True) {pw.println ("message sent by client");p W.flush (); line = Br.readline (); System.out.println (line);}} public static void Main (string[] args) throws IOException {new Normalclient (). Initclient ("127.0.0.1", 8000). read ();}}
Java NIO Learning Notes