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

          真正的快樂來源于創造

            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)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 方正县| 三江| 安吉县| 阜康市| 林周县| 延津县| 芦溪县| 兴文县| 白沙| 平阳县| 翁源县| 金平| 和硕县| 平泉县| 肃宁县| 车致| 大厂| 曲阳县| 呼和浩特市| 南丰县| 修水县| 新巴尔虎右旗| 固始县| 邵阳市| 鹿邑县| 太湖县| 邮箱| 阳西县| 明溪县| 呼伦贝尔市| 石柱| 钟山县| 佛教| 通城县| 东光县| 阿鲁科尔沁旗| 静宁县| 龙海市| 平邑县| 蒙自县| 丘北县|