日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
用nio實(shí)現(xiàn)Echo服務(wù)

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

目前成都創(chuàng)新互聯(lián)公司已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、網(wǎng)站改版維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、公主嶺網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

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 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.                         // 畢竟這樣多注冊的無用的事件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("有新的讀??!地址:" + 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.                             //斷開連接后,取消此鍵的通道到其選擇器的注冊  
  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 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也可以像下面這樣來實(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 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,呵呵,不用注冊SelectionKey.OP_CONNECT監(jiān)聽事件。呵呵...

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


當(dāng)前文章:用nio實(shí)現(xiàn)Echo服務(wù)
文章路徑:http://www.dlmjj.cn/article/dpcheoi.html