Socket Channel
The above describes the channel, file channel, this article describes the socket channel, the socket channel and the file channel has a different characteristics, three points said:
1. NIO's socket channel classes can run in nonblocking mode and are selectable, and these two performance can activate large programs (such as network servers and middleware components) with great scalability and flexibility, so there is no need to use a single thread for each socket connection . This feature avoids the overall context-switching overhead required to manage a large number of threads, and with the NIO class, one or several threads can manage hundreds of active socket connections with little or no performance loss
2. All socket channel classes (Datagramchannel, Socketchannel, and Serversocketchannel) will be created with a corresponding socket object when instantiated. Are the classes (sockets, ServerSocket, and Datagramsocket) that we are familiar with from java.net, which can be obtained from the channel class by calling the socket () method, in addition, These three java.net classes now have a Getchannel () method
3, each socket channel (in the Java.nio.channels package) has an associated Java.net.socket object, which is not the case, if the traditional way (direct instantiation) of a socket object is created, It will not have an associated socketchannel and its Getchannel () method will always return null
Generally speaking, this is the socket channel to grasp the knowledge point of knowledge points, not difficult, remember and through their own code/view JDK source to deepen understanding.
Non-blocking mode
The previous 1th said that the NIO socket channel could be run in nonblocking mode, although the statement was simple but far-reaching. The blocking nature of traditional Java sockets was once one of the most important constraints in Java program scalability, and non-blocking I/O is the foundation of many complex, high-performance program constructs.
To place a socket channel in nonblocking mode, rely on the selectablechannel of the socket channel class, and look at the simple definition of this class:
public abstract class selectablechannel extends abstractinterruptiblechannel implements channel{... public abstract void configureblocking (throws IOException; public abstract boolean isblocking (); public abstract Object Blocknglock (); ...}
Because this article is about the socket channel, the methods associated with selectors are omitted, and the omitted content is described in the next article.
As can be seen from the API of Selectablechannel, setting or resetting the blocking mode of a channel is simple, as long as the Configureblocking () method is called, the pass parameter value is set to block mode, A parameter value of FALSE is set to non-blocking mode, which is as simple as this. At the same time, we can call the Isblocking () method to determine which mode a socket channel is currently in.
Occasionally, we will also need to place the blocking mode of the socket channel changed, so there is a Blockinglock () method in the API that returns a non-transparent object reference, and the returned object is used internally when the channel implementation modifies the blocking mode. Only the thread that owns the lock on this object can change the blocking mode of the channel, which is handy for ensuring that the blocking mode of the socket channel does not change and that the blocking mode is temporarily changed without affecting other threads while executing the critical part of the code.
Socket channel service-side program
OK, let's look at how the Socket Channel server program should be written:
1 Public classNonblockingsocketserver2 {3 Public Static voidMain (string[] args)throwsException4 {5 intPort = 1234;6 if(Args! =NULL&& args.length > 0)7 {8Port = Integer.parseint (args[0]);9 }TenServersocketchannel SSC =Serversocketchannel.open (); OneSsc.configureblocking (false); AServerSocket SS =Ssc.socket (); -Ss.bind (Newinetsocketaddress (port)); -System.out.println ("Start waiting for the client's data! Time is "+System.currenttimemillis ()); the while(true) - { -Socketchannel sc =ssc.accept (); - if(sc = =NULL) + { - //If there is currently no data, wait 1 seconds for the data to be polled again, you can use selector here after learning selector +Thread.Sleep (1000); A } at Else - { -SYSTEM.OUT.PRINTLN ("Client already has data coming, client IP is:" +Sc.socket (). Getremotesocketaddress () -+ ", Time is" +System.currenttimemillis ()); -Bytebuffer BB = bytebuffer.allocate (100); - Sc.read (BB); in Bb.flip (); - while(Bb.hasremaining ()) to { +System.out.print ((Char) Bb.get ()); - } the sc.close (); *System.exit (0); $ }Panax Notoginseng } - } the}
The entire code flow is generally the case, nothing particularly worth noting, note the 18th line ~ 22nd Line, because here has not talked about selector, so when the client socket does not arrive at the time of the choice of processing is every 1 seconds polling.
Socket Channel client program
The server side often uses non-blocking socket access, because they make it easier to manage many socket channels at the same time, but the client does not insist, because the client initiates the socket operation is often relatively small, and is one after another initiated. However, it is also beneficial to have a socket channel with one or several non-blocking modes on the client, for example, with a non-blocking socket channel, the GUI program can focus on user requests and concurrently maintain sessions with one or more servers. In many programs, nonblocking mode is useful, so let's look at how the client should use the Socket channel:
1 Public classnonblockingsocketclient2 {3 Private Static FinalString str = "Hello world!";4 Private Static FinalString Remoteip = "127.0.0.1";5 6 Public Static voidMain (string[] args)throwsException7 {8 intPort = 1234;9 if(Args! =NULL&& args.length > 0)Ten { OnePort = Integer.parseint (args[0]); A } -Socketchannel sc =Socketchannel.open (); -Sc.configureblocking (false); theSc.connect (Newinetsocketaddress (REMOTEIP, Port)); - while(!sc.finishconnect ()) - { -System.out.println ("with" + Remoteip + "Connection is being established, please wait! "); +Thread.Sleep (10); - } +SYSTEM.OUT.PRINTLN ("The connection is established, the content to be written to the specified ip+ port!") Time is "+System.currenttimemillis ()); ABytebuffer BB =bytebuffer.allocate (Str.length ()); at Bb.put (Str.getbytes ()); -Bb.flip ();//Be sure to reverse the data before writing the buffer (flip) - Sc.write (BB); - bb.clear (); - sc.close (); - } in}
It is very convenient to read and write data through the channel, which is almost the same as normal socket operation. Again, however, the channel can only manipulate the byte buffer, which is the Bytebuffer data .
Run results show
The above code, in order to show the results of the need for the key points are added time to print, so that the results will be clearer to see the result.
First run the service-side program (note that you can not run the client program first, if you run the client program, the client program will be thrown because the server does not open the listener connectionexception), look at:
See the Red Square, at this point the program is running, then run the client program:
See that the client has "Hello world!" The socket is written and passed through the channel to the server side, and the box is dimmed to show that the program is running. Now look at what's changed on the server side:
See the server side print out the string "Hello world!", and the box dimmed, the program runs the end, which is consistent with the code.
Of course, the client sees the time is XXX10307, the server side sees the time is XXX10544, this is very normal, because said earlier, the server side program is every second polling whether has the socket arrives.
Java Nio4:socket Channel