posts - 28,  comments - 15,  trackbacks - 0
              在讀Amoeba源碼的時候,里面采用java NIO進行通信管理,以前也了解過一些關(guān)于這方面的知識但是都不太系統(tǒng),最近兩天抽時間對這塊進行一下掃盲。我主要參考以下兩篇文章,個人認為這兩篇文章還是不錯的入門級文章,講的比較通俗易懂。
          1.http://www.ibm.com/developerworks/cn/education/java/j-nio/section11.html
          比較系統(tǒng)的講述了Channel(通道)、Buffer(緩沖區(qū))、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服務(wù),客戶端向echo服務(wù)器發(fā)送一段信息,echo收到信息后,返回給客戶端,然后,連接關(guān)閉。代碼如下:
          /***************************************/
          客戶端代碼:
          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("好了克隆技術(shù)杜洛克防水堵漏開發(fā)!");
                                  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();
                              }

                          }

                      }
              
                  }

              }

          }


          /*********************************************/
          服務(wù)端代碼:

          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};   //默認監(jiān)聽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();
                                  
                                  
          /*返回信息后關(guān)閉連接*/
                                  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  回復  更多評論
            

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


          網(wǎng)站導航:
           
          <2011年6月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          常用鏈接

          留言簿(1)

          隨筆分類(17)

          隨筆檔案(28)

          文章分類(30)

          文章檔案(30)

          相冊

          收藏夾(2)

          hibernate

          java基礎(chǔ)

          mysql

          xml

          關(guān)注

          壓力測試

          算法

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 96363
          • 排名 - 601

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 乌鲁木齐市| 明溪县| 宜昌市| 公安县| 那坡县| 霍邱县| 凯里市| 泗水县| 竹北市| 得荣县| 胶南市| 郸城县| 蓬莱市| 贞丰县| 咸阳市| 梅河口市| 丹东市| 齐齐哈尔市| 铅山县| 金溪县| 巴中市| 武陟县| 永春县| 墨玉县| 伊川县| 平谷区| 贺州市| 加查县| 高淳县| 荆门市| 崇信县| 海宁市| 银川市| 同江市| 衡阳市| 永嘉县| 瑞昌市| 崇左市| 宁远县| 青州市| 苏尼特左旗|