Java uses NIO to establish a Socket server

Source: Internet
Author: User

Java uses NIO to establish a Socket server

The Socket Channel registers an action on the Selector. The Selector uses the select action to monitor the actions of all the channels registered with the Selector. If a corresponding action is detected, the return value is selectedKeys, and each SelectionKey is obtained manually for processing. Of course, NIO can not only accept Socket channels, but also file operations and other IO operations.

AD: WOT2015 Internet O & M and Developer Conference selling tickets

 

Traditional Java IO uses Socket to establish a server and receive client connections. Generally, a thread is created for each connection. If the number of connections is large, the server overhead will also be huge .. The following figure shows the NIO principle:

The Socket Channel registers an action on the Selector. The Selector uses the select action to monitor the actions of all the channels registered with the Selector. If a corresponding action is detected, the return value is selectedKeys, and each SelectionKey is obtained manually for processing. Of course, NIO can not only accept Socket channels, but also file operations and other IO operations.

Job Requirements:

Use socket programming to implement a simple file server. The client program implements the put function (transferring a file from the local to the file server) and get function (saving a remote file as a local file from the file server ). The client and the file server are not on the same machine.

put [-h hostname] [-p portname] local_filename remote_filenameget [-h hostname] [-p portname] remote_filename local_filename

The server does not use nio. The socket code for using io directly is as follows:

 
  1. Import java. io .*;
  2. Import java.net. ServerSocket;
  3. Import java.net. Socket;
  4.  
  5. Public class ServerMain {
  6.  
  7. Public static void main (String [] args ){
  8.  
  9. Class SocketThread extends Thread {
  10.  
  11. Private Socket socket;
  12. Private byte [] buf;
  13. Private int len = 0;
  14. Public SocketThread (Socket socket ){
  15. This. socket = socket;
  16. Buf = new byte [1024];
  17. }
  18.  
  19. @ Override
  20. Public void run (){
  21. Try {
  22. DataInputStream dis = new DataInputStream (socket. getInputStream ());
  23. DataOutputStream dos = new DataOutputStream (socket. getOutputStream ());
  24.  
  25. // String command = dis. readUTF ();
  26. Len = dis. read (buf );
  27. String command = new String (buf, 0, len );
  28.  
  29. System. out. println ("command =" + command );
  30.  
  31. String [] temp = command. split ("");
  32. Command = temp [0]; // whether the command is put or get
  33. String filename = temp [1]; // file name
  34.  
  35. File file = new File ("C: \", filename); // assume that the File is on drive C.
  36. If (command. equals ("get ")){
  37. If (! File. exists ()){
  38. // Dos. writeUTF ("notexists ");
  39. Dos. write ("notexists". getBytes ());
  40. Dos. flush ();
  41. System. out. println ("this file is not available and cannot be downloaded! ");
  42. Dis. close ();
  43. Dos. close ();
  44. Socket. close ();
  45. Return;
  46. }
  47. // Dos. writeUTF ("DownloadReady" + file. length ());
  48. Dos. write ("prepare to download". getBytes ());
  49. Dos. flush ();
  50.  
  51. System. out. println ("the file is being downloaded ...");
  52. DataInputStream FD = new DataInputStream (new BufferedInputStream (new FileInputStream (file )));
  53.  
  54. While (len = FS. read (buf ))! =-1 ){
  55. Dos. write (buf, 0, len );
  56. }
  57. Dos. flush ();
  58.  
  59. FCM. close ();
  60. System. out. println ("file transfer completed ");
  61. }
  62. Else {
  63. // Dos. writeUTF ("UploadReady ");
  64. Dos. write ("UploadReady". getBytes ());
  65. Dos. flush ();
  66.  
  67. System. out. println ("accepting file upload ...");
  68. DataOutputStream fileOut =
  69. New DataOutputStream (new BufferedOutputStream (new FileOutputStream (file )));
  70.  
  71. While (len = dis. read (buf ))! =-1 ){
  72. FileOut. write (buf, 0, len );
  73. }
  74. System. out. println ("uploaded! ");
  75. FileOut. close ();
  76. }
  77. Dis. close ();
  78. Dos. close ();
  79. Socket. close ();
  80. } Catch (Exception e ){
  81. E. printStackTrace ();
  82. }
  83. }
  84.  
  85. }
  86.  
  87. System. out. println ("waiting for client connection ....");
  88. Int index = 0;
  89. Try {
  90. ServerSocket server = new ServerSocket (9527,300); // port number 9527 maximum number of connections allowed 300
  91. While (true ){
  92. Socket socket = server. accept ();
  93. System. out. println ("received" + (++ index) + "connection ");
  94. New SocketThread (socket). start (); // create a thread for each connection
  95. }
  96. } Catch (Exception e ){
  97. E. printStackTrace ();
  98. }
  99. }
  100. }

The code for using the Socket server established by NIO is as follows:

 
  1. Import java. io. BufferedInputStream;
  2. Import java. io. BufferedOutputStream;
  3. Import java. io. DataInputStream;
  4. Import java. io. DataOutputStream;
  5. Import java. io. File;
  6. Import java. io. FileInputStream;
  7. Import java. io. FileOutputStream;
  8. Import java. io. IOException;
  9. Import java.net. InetSocketAddress;
  10. Import java. nio. ByteBuffer;
  11. Import java. nio. CharBuffer;
  12. Import java. nio. channels. SelectionKey;
  13. Import java. nio. channels. Selector;
  14. Import java. nio. channels. ServerSocketChannel;
  15. Import java. nio. channels. SocketChannel;
  16. Import java. nio. charset. Charset;
  17. Import java. nio. charset. CharsetDecoder;
  18. Import java. nio. charset. CharsetEncoder;
  19. Import java. util. Iterator;
  20.  
  21. Public class NewSocketServer {
  22.  
  23. Private static final int port = 9527;
  24. Private Selector selector;
  25. Private ByteBuffer clientBuffer = ByteBuffer. allocate (1024 );
  26. Private CharsetDecoder decoder = Charset. forName ("GB2312"). newDecoder ();
  27. Private CharsetEncoder encoder = Charset. forName ("GB2312"). newEncoder ();
  28. // Encoding and decoding format is set to GBK also line. UTF-8 is not good, Chinese garbled (the premise is that the client did not set any encoding and decoding format)
  29.  
  30. Public void setListener () throws Exception {
  31.  
  32. Selector = Selector. open (); // open the selector
  33.  
  34. ServerSocketChannel server = ServerSocketChannel. open (); // defines a ServerSocketChannel
  35. Server. socket (). bind (new InetSocketAddress (port); // ServerSocketChannel binding port
  36. Server. configureBlocking (false); // configure the channel to use the non-blocking mode
  37. Server. register (selector, SelectionKey. OP_ACCEPT); // This channel registers the action of accepting connections on the selector.
  38.  
  39. While (true)
  40. {
  41. Selector. select (); // select () will be blocked until the channel registered on the selector has the corresponding message read
  42. Iterator iter = selector. selectedKeys (). iterator ();
  43. While (iter. hasNext ()){
  44. SelectionKey key = (SelectionKey) iter. next ();
  45. Iter. remove (); // Delete the message
  46. Process (key); // process in the current thread. (For efficiency, this message is generally processed in another thread)
  47. }
  48. }
  49. }
  50.  
  51. Private void process (SelectionKey key) throws IOException {
  52. If (key. isAcceptable () {// receives the request
  53. ServerSocketChannel server = (ServerSocketChannel) key. channel ();
  54. SocketChannel channel = server. accept (); // similar to the socket of io, the accept function of ServerSocketChannel returns SocketChannel
  55. Channel. configureBlocking (false); // sets the non-blocking mode.
  56. SelectionKey sKey = channel. register (selector, SelectionKey. OP_READ );
  57. SKey. attach ("read_command"); // After receiving the connection request, you can set an ID for each connection.
  58. }
  59. Else if (key. isReadable () {// read information
  60. SocketChannel channel = (SocketChannel) key. channel ();
  61. String name = (String) key. attachment ();
  62. If (name. equals ("read_command ")){
  63. Int count = channel. read (clientBuffer );
  64. If (count> 0 ){
  65. ClientBuffer. flip ();
  66. CharBuffer charBuffer = decoder. decode (clientBuffer );
  67. String command = charBuffer. toString ();
  68.  
  69. // Command Format: get abc.png or put aaa.png
  70. System. out. println ("command =" + command); // obtain the command from the client.
  71.  
  72. String [] temp = command. split ("");
  73. Command = temp [0]; // whether the command is put or get
  74. String filename = temp [1]; // file name
  75.  
  76. SelectionKey sKey = channel. register (selector, SelectionKey. OP_WRITE );
  77. If (command. equals ("put") sKey. attach ("UploadReady #" + filename); // File Name of the channel to be protected
  78. Else if (command. equals ("get ")){
  79. If (! New File ("C :\\", filename). exists () {// assume that all files are in the C root directory.
  80. System. out. println ("this file is not available and cannot be downloaded! ");
  81. SKey. attach ("notexists ");
  82. }
  83. Else sKey. attach ("DownloadReady #" + filename); // File Name of the channel to be protected
  84. }
  85. } Else {
  86. Channel. close ();
  87. }
  88. }
  89. Else if (name. startsWith ("read_file") {// you can open a new thread file or use NIO
  90. DataOutputStream fileOut =
  91. New DataOutputStream (
  92. New BufferedOutputStream (
  93. New FileOutputStream (
  94. New File ("C: \", name. split ("#") [1]);
  95.  
  96. Int passlen = channel. read (clientBuffer );
  97. While (passlen> = 0 ){
  98. ClientBuffer. flip ();
  99. FileOut. write (clientBuffer. array (), 0, passlen );
  100. Passlen = channel. read (clientBuffer );
  101. }
  102. System. out. println ("uploaded! ");
  103. FileOut. close ();
  104. Channel. close ();
  105. }
  106. ClientBuffer. clear ();
  107. }
  108. Else if (key. isWritable () {// write event
  109. SocketChannel channel = (SocketChannel) key. channel ();
  110. String flag = (String) key. attachment ();
  111. If (flag. startsWith ("downloading") {// you can open a new thread file or use NIO
  112. DataInputStream FD = new DataInputStream (
  113. New BufferedInputStream (
  114. New FileInputStream (
  115. New File ("C :\\", flag. split ("#") [1]);
  116.  
  117. Byte [] buf = new byte [1, 1024];
  118. Int len = 0;
  119. While (len = FS. read (buf ))! =-1 ){
  120. Channel. write (ByteBuffer. wrap (buf, 0, len ));
  121. }
  122. FCM. close ();
  123. System. out. println ("file transfer completed ");
  124. Channel. close ();
  125. }
  126. Else if (flag. equals ("notexists ")){
  127. // Channel. write (encoder. encode (CharBuffer. wrap (flag )));
  128. Channel. write (ByteBuffer. wrap (flag. getBytes (); // The client can directly receive Chinese characters without encoding or garbled characters.
  129. Channel. close ();
  130. }
  131. Else if (flag. startsWith ("UploadReady ")){
  132. Channel. write (encoder. encode (CharBuffer. wrap ("UploadReady ")));
  133.  
  134. // If you do not re-register the read operation selector of this channel and select this channel, it will always be a write operation, and you will not be able to jump to the above process for receiving uploads.
  135. SelectionKey sKey = channel. register (selector, SelectionKey. OP_READ); // register is overwritten ????!!!
  136. SKey. attach ("read_file #" + flag. split ("#") [1]);
  137. // Key. attach ("read_file #" + flag. split ("#") [1]); // select cannot read
  138. }
  139. Else if (flag. startsWith ("DownloadReady ")){
  140. Channel. write (ByteBuffer. wrap ("prepare to download". getBytes ()));
  141. // Channel. write (encoder. encode (CharBuffer. wrap ("prepare to download ")));
  142. Key. attach ("downloading #" + flag. split ("#") [1]);
  143. }
  144. }
  145. }
  146.  
  147. Public static void main (String [] args ){
  148.  
  149. Try {
  150. System. out. println ("waiting for" + port + "port client connection .....");
  151. New NewSocketServer (). setListener ();
  152. } Catch (Exception e ){
  153. E. printStackTrace ();
  154. }
  155.  
  156. }
  157. }

The client code is as follows:

 
  1. Import java. io .*;
  2. Import java.net. InetAddress;
  3. Import java.net. Socket;
  4. Import java. util. collections;
  5.  
  6. Public class ClientMain {
  7.  
  8. Private int ServerPort = 9527;
  9. Private String ServerAddress = "192.168.1.154 ";
  10. Private String GetOrPut = "get ";
  11. Private String local_filename = "";
  12. Private String remote_filename = "";
  13. Private byte [] buf;
  14. Private int len;
  15. Class SocketThread extends Thread {
  16.  
  17. @ Override
  18. Public void run (){
  19. Try {
  20.  
  21. File file = new File ("C: \", local_filename); // assume that the File is placed on drive C.
  22. If (! File. exists () & GetOrPut. equals ("put ")){
  23. System. out. println ("this file does not exist locally and cannot be uploaded! ");
  24. Return;
  25. }
  26.  
  27. InetAddress loalhost = InetAddress. getLocalHost ();
  28. Socket socket = new Socket (ServerAddress, ServerPort, loalhost, 44 );
  29. // Server IP address port number local IP local port number
  30. DataInputStream dis = new DataInputStream (socket. getInputStream ());
  31. DataOutputStream dos = new DataOutputStream (socket. getOutputStream ());
  32.  
  33. // Dos. writeUTF (GetOrPut + "" + remote_filename); // connection between writeUTF and writeUTF on the server side if it is an io socket
  34. Dos. write (GetOrPut + "" + remote_filename). getBytes ());
  35. Dos. flush ();
  36.  
  37. // String tempString = dis. writeUTF ();
  38. Buf = new byte [1024];
  39. Len = dis. read (buf );
  40. String tempString = new String (buf, 0, len); // server feedback
  41.  
  42. // System. out. println (tempString );
  43. If (tempString. equals ("notexists ")){
  44. System. out. println ("the server does not have this file and cannot download it! ");
  45. Dos. close ();
  46. Dis. close ();
  47. Socket. close ();
  48. Return;
  49. }
  50.  
  51. If (tempString. startsWith ("prepare to download ")){
  52. DataOutputStream fileOut =
  53. New DataOutputStream (new BufferedOutputStream (new FileOutputStream (file )));
  54.  
  55. While (len = dis. read (buf ))! =-1 ){
  56. FileOut. write (buf, 0, len );
  57. }
  58. System. out. println ("download completed! ");
  59. FileOut. close ();
  60. Dos. close ();
  61. Dis. close ();
  62. Socket. close ();
  63. }
  64. Else if (tempString. equals ("UploadReady ")){
  65. System. out. println ("uploading file .......");
  66. DataInputStream FD = new DataInputStream (new BufferedInputStream (new FileInputStream (file )));
  67.  
  68. While (len = FS. read (buf ))! =-1 ){
  69. Dos. write (buf, 0, len );
  70. }
  71. Dos. flush ();
  72. System. out. println ("uploaded! ");
  73. FCM. close ();
  74. Dis. close ();
  75. Dos. close ();
  76. Socket. close ();
  77. }
  78.  
  79. } Catch (Exception e ){
  80. E. printStackTrace ();
  81. }
  82. }
  83.  
  84. }
  85.  
  86. Public boolean checkCommand (String command)
  87. {
  88. If (! Command. startsWith ("put ")&&! Command. startsWith ("get ")){
  89. System. out. println ("input command error ");
  90. Return false;
  91. }
  92.  
  93. Int index =-1;
  94. String temp = "";
  95. String [] tempStrings = null;
  96.  
  97. If (index = command. indexOf ("-h")> 0 ){
  98. Temp = command. substring (index + 3 );
  99. Temp = temp. substring (0, temp. indexOf (''));
  100. ServerAddress = temp;
  101. }
  102. If (index = command. indexOf ("-p")> 0 ){
  103. Temp = command. substring (index + 3 );
  104. Temp = temp. substring (0, temp. indexOf (''));
  105. ServerPort = Integer. valueOf (temp );
  106. }
  107.  
  108. TempStrings = command. split ("");
  109. If (command. startsWith ("put ")){
  110. GetOrPut = "put ";
  111. Local_filename = tempStrings [tempStrings. length-2];
  112. Remote_filename = tempStrings [tempStrings. length-1];
  113. }
  114. Else if (command. startsWith ("get ")){
  115. GetOrPut = "get ";
  116. Local_filename = tempStrings [tempStrings. length-1];
  117. Remote_filename = tempStrings [tempStrings. length-2];
  118. }
  119.  
  120. Return true;
  121. }
  122.  
  123. Public static void main (String [] args ){
  124. ClientMain thisC = new ClientMain ();
  125. Pipeline SC = new pipeline (System. in );
  126. String commandString = "";
  127. Do {
  128. System. out. println ("Enter the command :");
  129. CommandString = SC. nextLine ();
  130. } While (! ThisC. checkCommand (commandString ));
  131.  
  132. ClientMain. SocketThread a = thisC. new SocketThread ();
  133. A. start ();
  134. }
  135. }

Related Article

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.