Some of the content is quoted from Xpbug blog.
When it comes to the socket server, the first reaction is to java.net.Socket this class. In fact, the concurrency and response time requirements are not high, can be implemented with java.net.Socket, such as writing a LAN chat tool, send files and so on. But its shortcomings are also obvious, need to self-acceptance of the thread maintenance, management buffer allocation, etc., I tried to use Java.net.Socket to complete a transient load in the thousands of people around the server, but because of late changes and maintenance of abnormal trouble and give up.
Java has been added to the new IO feature since 1.4, which is the NIO introduced in this article. The following is a sample code for a server:
1 Public classEchoserver {2 Public StaticSelectorloop Connectionbell;3 Public StaticSelectorloop Readbell;4 Public Booleanisreadbellrunning=false;5 6 Public Static voidMain (string[] args)throwsIOException {7 Newechoserver (). StartServer ();8 }9 Ten //Start the server One Public voidStartServer ()throwsIOException { A //prepare an alarm clock. When a link comes in, it rings. -Connectionbell =NewSelectorloop (); - the //get ready for an alarm when a read event comes in. -Readbell =NewSelectorloop (); - - //open a server channel to listen +Serversocketchannel SSC =Serversocketchannel.open (); - //turn on non-blocking mode +Ssc.configureblocking (false); A atServerSocket socket =Ssc.socket (); -Socket.bind (NewInetsocketaddress ("localhost", 7878)); - - //set the alarm clock to monitor the reported events, this alarm clock only listen to new connection events. - Ssc.register (Connectionbell.getselector (), selectionkey.op_accept); - NewThread (Connectionbell). Start (); in } - to //Selector Polling Thread class + Public classSelectorloopImplementsRunnable { - PrivateSelector Selector; the PrivateBytebuffer temp = bytebuffer.allocate (1024); * $ PublicSelectorloop ()throwsIOException {Panax Notoginseng This. selector =Selector.open (); - } the + PublicSelector Getselector () { A return This. selector; the } + - @Override $ Public voidrun () { $ while(true) { - Try { - //blocked, will continue only if at least one registered event occurs. the This. Selector.select (); - WuyiSet<selectionkey> Selectkeys = This. Selector.selectedkeys (); theIterator<selectionkey> it =selectkeys.iterator (); - while(It.hasnext ()) { WuSelectionkey key =It.next (); - It.remove (); About //handles events. You can use multithreading to handle it. $ This. Dispatch (key); - } -}Catch(IOException e) { - e.printstacktrace (); A}Catch(interruptedexception e) { + e.printstacktrace (); the } - } $ } the the Public voidDispatch (Selectionkey Key)throwsIOException, interruptedexception { the if(Key.isacceptable ()) { the //This is a connection accept event, and this event is registered on Serversocketchannel. -Serversocketchannel SSC =(Serversocketchannel) Key.channel (); in //accept a connection. theSocketchannel sc =ssc.accept (); the About //registers the Read event with the channel for the new connection. Use Readbell alarms. theSc.configureblocking (false); the Sc.register (Readbell.getselector (), selectionkey.op_read); the + //if the read thread has not started yet, start a read thread. - synchronized(Echoserver. This) { the if(! Echoserver. This. isreadbellrunning) {BayiEchoserver. This. isreadbellrunning =true; the NewThread (Readbell). Start (); the } - } - the}Else if(Key.isreadable ()) { the //This is a read event, and this event is registered on Socketchannel. theSocketchannel sc =(Socketchannel) Key.channel (); the //write data to buffer - intCount =Sc.read (temp); the if(Count < 0) { the //The client has been disconnected. the Key.cancel ();94 sc.close (); the return; the } the //toggles the buffer to the read state, and the internal pointer is returned to bits.98 Temp.flip (); AboutString msg = charset.forname ("UTF-8"). Decode (temp). toString (); -System.out.println ("Server received [" +msg+ "] from client address:" +sc.getremoteaddress ());101 102Thread.Sleep (1000);103 //echo back.104Sc.write (Bytebuffer.wrap (Msg.getbytes (Charset.forname ("UTF-8"))))); the 106 //Empty buffer107 temp.clear ();108 }109 }111 } the 113}
OK, the original comments are very detailed, here to further parse this code.
The first is the Java.nio.channels.ServerSocketChannel class.
Java NIO non-blocking socket server build