當柳上原的風吹向天際的時候...

          真正的快樂來源于創造

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
          注意:
          1.NIO主要用于服務端,若用來客戶端相對于它帶來的額外復雜性有點不值得。
          2.用于編碼解碼字符集請根據您的機器缺省字符集進行調整,如GB2312,GBK,UTF-8,UTF-16等,若出現亂碼請更換之。
          3.BufferSize請根據您可能發送接收的最大字符串長度進行相應調整。

          代碼:
          package com.heyang.biz.server.test.nio;

          import java.net.InetSocketAddress;
          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;


          /**
           * NIO 服務器
           * 說明:
           * 作者:何楊(heyang78@gmail.com)
           * 創建時間:2011-1-3 下午12:09:02
           * 修改時間:2011-1-3 下午12:09:02
           
          */
          public class NIOServer{
              
          // 本地字符集
              private static final String LocalCharsetName = "gb2312";

              
          // 本地服務器監聽的端口
              private static final int Listenning_Port=8888;
              
              
          // 緩沖區大小
              private static final int Buffer_Size=1024;
              
              
          // 超時時間,單位毫秒
              private static final int TimeOut=3000;
              
              
          public static void main(String[] args) throws Exception{
                  
          // 創建一個在本地端口進行監聽的服務Socket信道.并設置為非阻塞方式
                  ServerSocketChannel serverChannel=ServerSocketChannel.open();
                  serverChannel.socket().bind(
          new InetSocketAddress(Listenning_Port));
                  serverChannel.configureBlocking(
          false);
                  
                  
          // 創建一個選擇器并將serverChannel注冊到它上面
                  Selector selector=Selector.open();
                  serverChannel.register(selector, SelectionKey.OP_ACCEPT);
                  
                  
          while(true){
                      
          // 等待某個信道就緒
                      if(selector.select(TimeOut)==0){
                          System.out.println(
          ".");
                          
          continue;
                      }
                      
                      
          // 獲得就緒信道的鍵迭代器
                      Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();
                      
                      
          // 使用迭代器進行遍歷就緒信道
                      while(keyIter.hasNext()){
                          SelectionKey key
          =keyIter.next();
                          
                          
          // 這種情況是有客戶端連接過來,準備一個clientChannel與之通信
                          if(key.isAcceptable()){
                              SocketChannel clientChannel
          =((ServerSocketChannel)key.channel()).accept();
                              clientChannel.configureBlocking(
          false);
                              clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(Buffer_Size));
                          }
                          
                          
          // 客戶端有寫入時
                          if(key.isReadable()){
                              
          // 獲得與客戶端通信的信道
                              SocketChannel clientChannel=(SocketChannel)key.channel();
                              
                              
          // 得到并重置緩沖區的主要索引值
                              ByteBuffer buffer=(ByteBuffer)key.attachment();
                              buffer.clear();
                              
                              
          // 讀取信息獲得讀取的字節數
                              long bytesRead=clientChannel.read(buffer);
                              
                              
          if(bytesRead==-1){
                                
          // 沒有讀取到內容的情況
                                clientChannel.close();
                              }
                              
          else{
                                
          // 將緩沖區準備為數據傳出狀態
                                buffer.flip();
                                
                                
          // 將獲得字節字符串(使用Charset進行解碼)   
                                String receivedString=Charset.forName(LocalCharsetName).newDecoder().decode(buffer).toString();
                                
                                
          // 控制臺打印出來
                                System.out.println("接收到信息:"+receivedString);
                                
                                
          // 準備發送的文本
                                String sendString="你好,客戶端. 已經收到你的信息"+receivedString;
                                
                                
          // 將要發送的字符串編碼(使用Charset進行編碼)后再進行包裝
                                buffer=ByteBuffer.wrap(sendString.getBytes(LocalCharsetName));
                                
                                
          // 發送回去
                                clientChannel.write(buffer);
                                
                                
          // 設置為下一次讀取或是寫入做準備
                                key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                              }
                          }
                          
                          keyIter.remove();
                      }
                  }
                  
              }
          }

          與之配合的客戶端代碼,沒有采用NIO方式。
          package com.heyang.biz.server.test.nio;

          import java.io.InputStream;
          import java.io.OutputStream;
          import java.io.PrintWriter;
          import java.net.Socket;
          import java.util.Scanner;



          public class TestClient{
              
          public static void main(String[] args) throws Exception{
                  Socket s
          =new Socket("127.0.0.1",8888);
                  
                  InputStream  inStram
          =s.getInputStream();
                  OutputStream outStream
          =s.getOutputStream();
                  
                  
          // 輸出
                  PrintWriter out=new PrintWriter(outStream,true);
                  
                  out.print(
          "getPublicKey你好!");
                  out.flush();

                  s.shutdownOutput();
          // 輸出結束
                  
                  
          // 輸入
                  Scanner in=new Scanner(inStram);
                  StringBuilder sb
          =new StringBuilder();
                  
          while(in.hasNextLine()){
                      String line
          =in.nextLine();
                      sb.append(line);
                  }
                  String response
          =sb.toString();
                  System.out.println(
          "response="+response);
              }
          }

          服務器端的輸出:
          .
          接收到信息:getPublicKey你好!
          .

          客戶端的輸出:
          response=你好,客戶端. 已經收到你的信息getPublicKey你好!
          posted on 2011-01-03 14:36 何楊 閱讀(4714) 評論(0)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 平武县| 黄龙县| 西华县| 谷城县| 揭东县| 安吉县| 遵义市| 华池县| 应用必备| 涟源市| 托克逊县| 余姚市| 永城市| 来凤县| 双柏县| 桑日县| 兴文县| 平乐县| 宜良县| 中牟县| 石嘴山市| 巴青县| 夏津县| 鄂伦春自治旗| 宜良县| 海门市| 永平县| 奈曼旗| 兰州市| 四平市| 景泰县| 将乐县| 建水县| 辛集市| 蒙阴县| 武隆县| 博客| 安泽县| 庆安县| 嘉善县| 新沂市|