自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用nio實(shí)現(xiàn)Echo服務(wù)

開發(fā) 后端
今天突然間想用nio實(shí)現(xiàn)個(gè)Echo服務(wù),程序?qū)崿F(xiàn)起來(lái)實(shí)現(xiàn)不算困難,但跑起來(lái)后,在Server端的ServerSocket完成accept之后,我的CPU總是跳到100%。嗯,小郁悶,后來(lái),才發(fā)現(xiàn)自己在Server端注冊(cè)了多余的監(jiān)聽事件SelectionKey.OP_WRITE,改過(guò)來(lái)后好多了,希望記住這個(gè)教訓(xùn)。

今天突然間想用nio實(shí)現(xiàn)個(gè)Echo服務(wù),程序?qū)崿F(xiàn)起來(lái)實(shí)現(xiàn)不算困難,但跑起來(lái)后,在Server端的ServerSocket完成accept之后,我的CPU總是跳到100%。嗯,小郁悶,后來(lái),才發(fā)現(xiàn)自己在Server端注冊(cè)了多余的監(jiān)聽事件SelectionKey.OP_WRITE,改過(guò)來(lái)后好多了,希望記住這個(gè)教訓(xùn)。

EchoServer.java

  1. package edu.dlut.zxf.nio;  
  2.  
  3. import java.io.IOException;  
  4. import java.net.InetAddress;  
  5. import java.net.InetSocketAddress;  
  6. import java.nio.ByteBuffer;  
  7. import java.nio.channels.SelectionKey;  
  8. import java.nio.channels.Selector;  
  9. import java.nio.channels.ServerSocketChannel;  
  10. import java.nio.channels.SocketChannel;  
  11. import java.util.Set;  
  12.  
  13. /**  
  14.  * Echo服務(wù)器  
  15.  * @author finux  
  16.  */ 
  17. public class EchoServer {  
  18.     public final static int BUFFER_SIZE = 1024//默認(rèn)端口  
  19.     public final static String HOST = "210.30.107.17";  
  20.     public final static int PORT = 8888;  
  21.       
  22.     public static void main(String[] args) {  
  23.         ServerSocketChannel ssc = null;  
  24.         //緩沖區(qū)  
  25.         ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);  
  26.         Selector selector = null;  
  27.         try {  
  28.             selector = Selector.open();  
  29.             ssc = ServerSocketChannel.open();  
  30.             ssc.socket().bind(new InetSocketAddress(InetAddress.getByName(HOST), PORT));  
  31.             ssc.configureBlocking(false);  
  32.             ssc.register(selector, SelectionKey.OP_ACCEPT);       
  33.             print("服務(wù)器啟動(dòng),準(zhǔn)備好連接...");  
  34.             while (selector.select() > 0) {       
  35.                 Set<SelectionKey> selectionKeys = selector.selectedKeys();  
  36.                 for (SelectionKey key: selectionKeys) {  
  37.                     if (key.isAcceptable()) {  
  38.                         SocketChannel sc = ssc.accept();  
  39.                         print("有新的連接!地址:" + sc.socket().getRemoteSocketAddress());  
  40.                         sc.configureBlocking(false);  
  41.                         sc.register(selector, SelectionKey.OP_READ);  
  42.                         // 不要寫成:  
  43.                         // sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);  
  44.                         // 畢竟這樣多注冊(cè)的無(wú)用的事件SelectionKey.OP_WRTE  
  45.                         // 如果是這樣,在完成accept后,CPU也許會(huì)跑到100%  
  46.                           
  47.                     }  
  48.                     //same to if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ) {  
  49.                     if (key.isReadable()) {   
  50.                         SocketChannel sc = (SocketChannel)key.channel();  
  51.                         print("有新的讀?。〉刂罚?quot; + sc.socket().getRemoteSocketAddress());                        
  52.                         buffer.clear();                       
  53.                         sc.read(buffer);  
  54.                         buffer.flip();  
  55.                         byte[] b = new byte[buffer.limit()];  
  56.                         buffer.get(b);  
  57.                         String s = new String(b);  
  58.                         if (s.equals("bye")) {  
  59.                             print("斷開連接:" + sc.socket().getRemoteSocketAddress());    
  60.                             //斷開連接后,取消此鍵的通道到其選擇器的注冊(cè)  
  61.                             key.cancel();  
  62.                             sc.close();  
  63.                             continue;  
  64.                         }  
  65.                         print("讀取的內(nèi)容為:" + s);     
  66.                         buffer.clear();  
  67.                         s = "echo: " + s;  
  68.                         buffer.put(s.getBytes());  
  69.                         buffer.flip();  
  70.                         sc.write(buffer);  
  71.                     }   
  72.                 }  
  73.                 selectionKeys.clear();  
  74.             }  
  75.         } catch(IOException e) {  
  76.             e.printStackTrace();  
  77.         }   
  78.     }  
  79.       
  80.     private static void print(String s) {  
  81.         System.out.println(s);  
  82.     }  

EchoClient.java

  1. package edu.dlut.zxf.nio;  
  2.  
  3. import java.util.Set;  
  4. import java.io.BufferedReader;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.net.InetSocketAddress;  
  8. import java.net.InetAddress;  
  9. import java.nio.ByteBuffer;  
  10. import java.nio.channels.SelectionKey;  
  11. import java.nio.channels.Selector;  
  12. import java.nio.channels.SocketChannel;  
  13.  
  14. /**  
  15.  * Echo客戶端  
  16.  * @author finux  
  17.  */ 
  18. public class EchoClient {  
  19.     public static void main(String[] args) {  
  20.         ByteBuffer buffer = ByteBuffer.allocate(EchoServer.BUFFER_SIZE);  
  21.         Selector selector = null;  
  22.         SocketChannel sc = null;  
  23.         try {  
  24.             selector = Selector.open();  
  25.             sc = SocketChannel.open();  
  26.             sc.configureBlocking(false);  
  27.             sc.connect(new InetSocketAddress(InetAddress.getByName(EchoServer.HOST), EchoServer.PORT));  
  28.             print("客戶端啟動(dòng),準(zhǔn)備連接...");  
  29.             if (sc.isConnectionPending()) {  
  30.                 sc.finishConnect();  
  31.             }  
  32.             print("完成連接");  
  33.             sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);  
  34.               
  35.             boolean writed = false;  
  36.             boolean down = false;  
  37.             while (!down && selector.select() > 0) {                  
  38.                 Set<SelectionKey> selectionKeys = selector.selectedKeys();  
  39.                 for (SelectionKey key: selectionKeys) {                   
  40.                     //int ops = key.readyOps();  
  41.                     //if ((ops & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && !writed) {  
  42.                     if (key.isWritable() && !writed) {  
  43.                         System.out.print("Input(bye to end): ");  
  44.                         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));   
  45.                         String s = br.readLine();  
  46.                         if (s != null && !s.trim().equals("")) {  
  47.                             buffer.clear();  
  48.                             buffer.put(s.getBytes());  
  49.                             buffer.flip();  
  50.                             sc.write(buffer);  
  51.                             writed = true;  
  52.                             if (s.equals("bye")) {  
  53.                                 down = true;  
  54.                                 break;  
  55.                             }  
  56.                         }  
  57.                     }  
  58.                     //if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ && writed) {  
  59.                     if (key.isReadable() && writed) {  
  60.                         buffer.clear();  
  61.                         sc.read(buffer);  
  62.                         buffer.flip();  
  63.                         byte[] b = new byte[buffer.limit()];  
  64.                         buffer.get(b);  
  65.                         print(new String(b));  
  66.                         writed = false;  
  67.                     }  
  68.                 }  
  69.                 selectionKeys.clear();  
  70.             }  
  71.         } catch(IOException e) {  
  72.             e.printStackTrace();  
  73.         }  
  74.     }  
  75.       
  76.     private static void print(String s) {  
  77.         System.out.println(s);  
  78.     }  

當(dāng)然EchoClient也可以像下面這樣來(lái)實(shí)現(xiàn):

EchoClient2.java

  1. package edu.dlut.zxf.nio;  
  2.  
  3. import java.util.Set;  
  4. import java.io.BufferedReader;  
  5. import java.io.IOException;  
  6. import java.io.InputStreamReader;  
  7. import java.net.InetSocketAddress;  
  8. import java.net.InetAddress;  
  9. import java.nio.ByteBuffer;  
  10. import java.nio.channels.SelectionKey;  
  11. import java.nio.channels.Selector;  
  12. import java.nio.channels.SocketChannel;  
  13.  
  14. /**  
  15.  * Echo客戶端2  
  16.  * @author finux  
  17.  */ 
  18. public class EchoClient2 {  
  19.     public static void main(String[] args) {  
  20.         ByteBuffer buffer = ByteBuffer.allocate(EchoServer.BUFFER_SIZE);  
  21.         Selector selector = null;  
  22.         SocketChannel sc = null;  
  23.         try {  
  24.             selector = Selector.open();  
  25.             sc = SocketChannel.open();  
  26.             sc.configureBlocking(false);  
  27.             sc.register(selector, SelectionKey.OP_CONNECT);  
  28.             sc.connect(new InetSocketAddress(InetAddress.getByName(EchoServer.HOST), EchoServer.PORT));  
  29.             print("客戶端啟動(dòng),準(zhǔn)備連接...");  
  30.               
  31.             boolean writed = false;  
  32.             boolean down = false;  
  33.             while (!down && selector.select() > 0) {                  
  34.                 Set<SelectionKey> selectionKeys = selector.selectedKeys();  
  35.                 for (SelectionKey key: selectionKeys) {                   
  36.                     //int ops = key.readyOps();  
  37.                     //if ((ops & SelectionKey.OP_CONNECT) == SelectionKey.OP_CONNECT) {  
  38.                     if (key.isConnectable()) {  
  39.                         print("完成連接!");  
  40.                         if (sc.isConnectionPending()) {  
  41.                             sc.finishConnect();  
  42.                         }  
  43.                         sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);                  
  44.                     }  
  45.                     //if ((ops & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE && !writed) {  
  46.                     if (key.isWritable() && !writed) {  
  47.                         //從準(zhǔn)備IO中讀取內(nèi)容  
  48.                         System.out.print("Input(bye to end): ");  
  49.                         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));   
  50.                         String s = br.readLine();  
  51.                         if (s != null && !s.trim().equals("")) {  
  52.                             buffer.clear();  
  53.                             buffer.put(s.getBytes());  
  54.                             buffer.flip();  
  55.                             sc.write(buffer);  
  56.                             writed = true;  
  57.                             if (s.equals("bye")) {  
  58.                                 down = true;  
  59.                                 break;  
  60.                             }  
  61.                         }  
  62.                     }  
  63.                     //if ((ops & SelectionKey.OP_READ) == SelectionKey.OP_READ && writed) {  
  64.                     if (key.isReadable() && writed) {  
  65.                         buffer.clear();  
  66.                         sc.read(buffer);  
  67.                         buffer.flip();  
  68.                         byte[] b = new byte[buffer.limit()];  
  69.                         buffer.get(b);  
  70.                         print(new String(b));  
  71.                         writed = false;  
  72.                     }  
  73.                 }  
  74.                 selectionKeys.clear();  
  75.             }  
  76.         } catch(IOException e) {  
  77.             e.printStackTrace();  
  78.         }  
  79.     }  
  80.       
  81.     private static void print(String s) {  
  82.         System.out.println(s);  
  83.     }  

但是這樣的話,顯然EchoClient2中的while循環(huán)中的for循環(huán)(若有n次),在每次循環(huán)中都會(huì)多出n-1次if判斷,就是下面這個(gè):

  1. if (key.isConnectable()) { 

所以,我個(gè)人更喜歡***個(gè)EchoClient,呵呵,不用注冊(cè)SelectionKey.OP_CONNECT監(jiān)聽事件。呵呵...

原文鏈接:http://finux.iteye.com/blog/368955

【編輯推薦】

  1. Java NIO 深入研究
  2. Java NIO聊天窗口實(shí)例
  3. Java NIO 經(jīng)典實(shí)例代碼
  4. Java NIO性能測(cè)試
  5. Java NIO TCP編程
責(zé)任編輯:林師授 來(lái)源: finux的博客
相關(guān)推薦

2023-03-31 07:49:51

syscall庫(kù)Echo Serve

2011-12-07 16:50:29

JavaNIO

2020-04-16 15:20:43

PHP前端BIO

2011-12-07 17:05:45

JavaNIO

2011-12-08 10:12:34

JavaNIO

2011-12-08 13:04:06

JavaNIO

2012-04-11 15:41:48

JavaNIO

2011-09-30 13:04:17

51CTO博客一周熱門監(jiān)控網(wǎng)絡(luò)

2022-11-04 08:29:12

NodejsHttp 服務(wù)

2023-08-22 11:00:16

云計(jì)算容器微服務(wù)

2011-03-11 09:51:47

Java NIO

2011-12-08 09:37:36

JavaNIO

2010-09-10 14:03:47

echo協(xié)議

2022-08-11 08:03:43

隊(duì)列

2018-06-15 10:25:43

Python HTTPFTP服務(wù)器

2018-12-06 09:23:33

2024-11-29 10:23:35

2014-01-02 15:16:42

PythonLinux服務(wù)器服務(wù)器監(jiān)控

2011-08-12 10:20:02

echo中文man

2010-09-17 16:27:16

ECHO OFF
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)