posts - 28,  comments - 15,  trackbacks - 0
              在讀Amoeba源碼的時候,里面采用java NIO進行通信管理,以前也了解過一些關于這方面的知識但是都不太系統,最近兩天抽時間對這塊進行一下掃盲。我主要參考以下兩篇文章,個人認為這兩篇文章還是不錯的入門級文章,講的比較通俗易懂。
          1.http://www.ibm.com/developerworks/cn/education/java/j-nio/section11.html
          比較系統的講述了Channel(通道)、Buffer(緩沖區)、position,limit,capacity in buffer等;其示例代碼在:
          http://code.google.com/p/astudy/source/browse/trunk/applications/astudy/nio/MultiPortEcho.java?spec=svn141&r=141

          2.http://tutorials.jenkov.com/java-nio/index.html
          這個站點也是一個不錯的入門級別介紹,雖然是e文,但講解的比較細致。

          3.我的demo
          這個小例子,模擬了一個echo服務,客戶端向echo服務器發送一段信息,echo收到信息后,返回給客戶端,然后,連接關閉。代碼如下:
          /***************************************/
          客戶端代碼:
          package com.zxl.channel;

          import java.io.IOException;
          import java.net.InetSocketAddress;
          import java.nio.ByteBuffer;
          import java.nio.channels.SelectionKey;
          import java.nio.channels.Selector;
          import java.nio.channels.SocketChannel;
          import java.nio.charset.Charset;
          import java.util.Set;

          public class EchoClient {

              
          /**
               * 
          @param args
               * 
          @throws IOException 
               
          */

              
          public static void main(String[] args) throws IOException {
                  
                  
                  SocketChannel channel 
          = SocketChannel.open();
                  channel.configureBlocking(
          false);    
                  InetSocketAddress s 
          = new InetSocketAddress("localhost",2000);
                  channel.connect(s);
                  
                  Selector selector 
          = Selector.open();
                  channel.register(selector, SelectionKey.OP_CONNECT
          |SelectionKey.OP_READ);
                  
                  Charset charset
          =Charset.forName("GBK");
                  
                  
          boolean isFinished = false;
                  
          while(!isFinished){
                      
          int num = selector.select();
                      
          if(num>0){
                          Set
          <SelectionKey> keys = selector.selectedKeys();
                          
          for(SelectionKey k:keys){
                              
          if(k.isConnectable()){
                                  SocketChannel sc 
          = (SocketChannel) k.channel();
                                  sc.configureBlocking(
          false);
                                  sc.finishConnect();
                                  sc.register(selector, SelectionKey.OP_READ);
                          
                                  ByteBuffer echoBuffer 
          = ByteBuffer.allocate(1024);
                                  ByteBuffer info 
          =charset.encode("好了克隆技術杜洛克防水堵漏開發!");
                                  echoBuffer.put(info);
                                  
                                  echoBuffer.flip();    
                              
                                  sc.write(echoBuffer);
                                  echoBuffer.clear();
                                  
                              }
          else if (k.isValid() && k.isReadable()) {
                                  ByteBuffer echoBuffer 
          = ByteBuffer.allocate(1024);
                                  SocketChannel sc 
          = (SocketChannel) k.channel();
                                  sc.read(echoBuffer);
                                  echoBuffer.flip();
                                  
                                  System.out.println(
          "echo server return:"+charset.decode(echoBuffer).toString());
                                  echoBuffer.clear();
                                  
                                  isFinished 
          = true;
                                  
                                  k.cancel();
                                  sc.close();
                                  selector.close();
                              }

                          }

                      }
              
                  }

              }

          }


          /*********************************************/
          服務端代碼:

          package com.zxl.channel;


          import java.io.IOException;
          import java.net.InetSocketAddress;
          import java.net.ServerSocket;
          import java.nio.ByteBuffer;
          import java.nio.channels.SelectionKey;
          import java.nio.channels.Selector;
          import java.nio.channels.ServerSocketChannel;
          import java.nio.channels.SocketChannel;
          import java.nio.charset.Charset;
          import java.util.Iterator;
          import java.util.Set;

          public class MultiPortEchoServer {

              
          private Charset charset=Charset.forName("GBK");
              
              
          private int[] ports;
              
              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  
                  
          int[] ps = {2000,2001};   //默認監聽2000,2001端口
                  
                  
          new MultiPortEchoServer(ps);

              }

              
              
          public MultiPortEchoServer(int[] ports){
                  
          this.ports = ports;
                  
          try {
                      go();
                  }
           catch (IOException e) {
                      
          // TODO Auto-generated catch block
                      e.printStackTrace();
                  }

              }

              
              
          public void go() throws IOException{
                  
                  Selector selector 
          = Selector.open();
                  
                  
          for(int i=0;i<ports.length;i++){
                      ServerSocketChannel channel 
          = ServerSocketChannel.open();
                      channel.configureBlocking(
          false);
                      ServerSocket socket 
          = channel.socket();
                      InetSocketAddress address 
          = new InetSocketAddress("localhost",ports[i]);
                      socket.bind(address);
                      
                      
          //注冊接受連接事件
                      channel.register(selector, SelectionKey.OP_ACCEPT);
                      
                      System.out.println( 
          "Going to listen on "+ports[i] ); 
                  }

                  
                  
          while(true){
                      
                      
          int num = selector.select();
                      Set
          <SelectionKey> keys = selector.selectedKeys();
                      Iterator
          <SelectionKey> iter = keys.iterator();
                      
          while(iter.hasNext()){
                          SelectionKey key 
          = iter.next();
                          
          if((key.readyOps()&SelectionKey.OP_ACCEPT)==SelectionKey.OP_ACCEPT){
                              ServerSocketChannel  ssc 
          = (ServerSocketChannel) key.channel();
                              SocketChannel sc 
          = ssc.accept();
                              sc.configureBlocking(
          false);
                              
                              sc.register(selector, SelectionKey.OP_READ);
                              iter.remove();
                          }
          else if((key.readyOps()&SelectionKey.OP_READ)==SelectionKey.OP_READ){
                              
                              SocketChannel sc 
          = (SocketChannel) key.channel();
                              
                              
          if(!sc.isOpen()){
                                  selector 
          = Selector.open();
                              }
          else{
                                  ByteBuffer echoBuffer 
          = ByteBuffer.allocate(1024);  
                                  
                                  
          //int x = sc.read(echoBuffer);
                                  while(sc.read(echoBuffer)>0){
                                      
                                      System.out.println( 
          "Echoed "+charset.decode(echoBuffer).toString()+" from "+sc.socket().getInetAddress().getHostAddress() );  
                                      echoBuffer.flip();
                                      sc.write(echoBuffer);
                                      echoBuffer.clear();
                                  }

                                  
                                  
                                  iter.remove();
                                  
                                  
          /*返回信息后關閉連接*/
                                  key.cancel();
                                  sc.close();
                              }

                          }

                      }

                      
                      keys.clear();
                  }

              }


          }




          posted on 2011-06-30 16:24 zhangxl 閱讀(2793) 評論(1)  編輯  收藏 所屬分類: java concurrency


          FeedBack:
          # re: Java NIO Demo
          2014-11-24 09:47 | zuidaima
          java demo學習實例教程源代碼下載:http://zuidaima.com/share/kjava-p1-s1.htm  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2014年11月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(28)

          文章分類(30)

          文章檔案(30)

          相冊

          收藏夾(2)

          hibernate

          java基礎

          mysql

          xml

          關注

          壓力測試

          算法

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 96363
          • 排名 - 601

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 兴安县| 定陶县| 怀仁县| 永定县| 博白县| 通州区| 长乐市| 延津县| 喀什市| 翼城县| 望城县| 田林县| 苗栗县| 奈曼旗| 怀柔区| 尖扎县| 喀喇| 泾川县| 任丘市| 克拉玛依市| 大兴区| 离岛区| 丹东市| 雷山县| 四子王旗| 偃师市| 开鲁县| 阿合奇县| 盐边县| 闻喜县| 廉江市| 延吉市| 古田县| 文安县| 钟祥市| 浦东新区| 呼和浩特市| 固镇县| 连云港市| 永城市| 常州市|