<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    少年阿賓

    那些青春的歲月

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

    根據網上的資料做些整理

    Java NIO API詳解

    http://www.tkk7.com/19851985lili/articles/93524.html

    這篇文章對nio的api講解比較全,可以幫助在宏觀上把握nio。

    BIO 方式使得整個處理過程和連接是綁定的,只要連接建立,無論客戶端是否有消息發送,都要進行等待處理,一定程度上浪費了服務器端的硬件資源,因此就有了NIO 方式。Java 對于 NIO 方式的支持是通過 Channel和 Selector 方式來實現,采用的方法為向 Channel注冊感興趣的事件,然后通過 Selector 來獲取到發生了事件的 key,如發生了相應的事件,則進行相應的處理,否則則不做任何處理,是典型的Reactor 模式,按照這樣的方式,就不用像 BIO 方式一樣,即使在沒有消息的情況下也需要占據一個線程來阻塞讀取消息,從而提升服務器的使用效率, 為實現 TCP/IP+NIO 方式的系統間通訊, Java 提供了 SocketChannel和 ServerSocketChannel兩個關鍵的類,網絡 IO 的操作則改為通過ByteBuffer 來實現,具體的基于 java實現TCP/IP+NIO 方式的通訊的方法如下所示。

    服務器端:

    package com.flyoung;

    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.util.Iterator;
    import java.util.Set;
    import java.nio.channels.SocketChannel;

    public class NIOServer {
        
    /*標志數字*/
        
    private static int flag = 0;
        
    /*定義緩沖區大小*/
        
    private static int block = 4096;
        
    /*接收緩沖區*/
        
    private static ByteBuffer receiveBuffer = ByteBuffer.allocate(block);
        
    /*發送緩沖區*/
        
    private static ByteBuffer sendBuffer = ByteBuffer.allocate(block);
        
    /*定義Selector*/
        
    private Selector selector;
        
        
    public NIOServer(int port) throws IOException{
            
    //打開服務器套接字通道
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            
    //服務器配置為非阻塞
            serverSocketChannel.configureBlocking(false);
            
    //檢索與此服務器套接字通道關聯的套接字
            ServerSocket serverSocket = serverSocketChannel.socket();
            
    //進行服務的綁定
            serverSocket.bind(new InetSocketAddress(port));
            
    //通過open()方法找到Selector
            selector = Selector.open();
            
    //注冊到selector
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println(
    "Server Start -----8888:");
        }
        
    //監聽
        public void listen() throws IOException{
            
    while(true){
                
    //監控所有注冊的 channel ,當其中有注冊的 IO 操作可以進行時,該函數返回,并將對應的 SelectionKey 加入 selected-key set
                selector.select();
                
    //Selected-key set 代表了所有通過 select() 方法監測到可以進行 IO 操作的 channel ,這個集合可以通過 selectedKeys() 拿到
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator
    <SelectionKey> iterator = selectionKeys.iterator();
                
    while(iterator.hasNext()){
                    SelectionKey selectionKey 
    = iterator.next();
                    handleKey(selectionKey);
                    iterator.remove();
                }
            }
            
        }
        
    //處理請求
        public void handleKey(SelectionKey selectionKey) throws IOException{
            
    //接受請求
            ServerSocketChannel serverSocketChannel = null;
            SocketChannel socketChannel 
    = null;
            String receiveText;
            String sendText;
            
    int count;
            
    //測試此鍵的通道是否準備好接受新的套接字連接
            if(selectionKey.isAcceptable()){
                
    //返回創建此鍵的通道
                serverSocketChannel = (ServerSocketChannel)selectionKey.channel();
                
    //接受客戶端建立連接的請求,并返回 SocketChannel 對象
                socketChannel = serverSocketChannel.accept();
                
    //配置為非阻塞
                socketChannel.configureBlocking(false);
                
    //注冊到selector
                socketChannel.register(selector, SelectionKey.OP_READ);
            }
    else if(selectionKey.isReadable()){
                
    //返回為之創建此鍵的通道
                socketChannel = (SocketChannel)selectionKey.channel();
                
    //將緩沖區清空,以備下次讀取
                receiveBuffer.clear();
                
    //將發送來的數據讀取到緩沖區
                
                count 
    = socketChannel.read(receiveBuffer);
            
                
                
    if(count>0){
                    receiveText 
    = new String(receiveBuffer.array(),0,count);
                    System.out.println(
    "服務器端接受到的數據---"+receiveText);
                    socketChannel.register(selector, SelectionKey.OP_WRITE);
                }
            }
    else if (selectionKey.isWritable()) {  
                
    //將緩沖區清空以備下次寫入  
                sendBuffer.clear();  
                
    // 返回為之創建此鍵的通道。  
                socketChannel = (SocketChannel) selectionKey.channel();  
                sendText
    ="message from server--" + flag++;  
                
    //向緩沖區中輸入數據  
                sendBuffer.put(sendText.getBytes());  
                 
    //將緩沖區各標志復位,因為向里面put了數據標志被改變要想從中讀取數據發向服務器,就要復位  
                sendBuffer.flip();  
                
    //輸出到通道  
                socketChannel.write(sendBuffer);  
                System.out.println(
    "服務器端向客戶端發送數據--:"+sendText);  
                socketChannel.register(selector, SelectionKey.OP_READ);  
            }  
            
        }
        
    public static void main(String[] args) throws IOException {
            
    int port = 8888
            NIOServer server 
    = new NIOServer(port);
            server.listen();
        }

    }

     

    客戶端

    package com.flyoung;

    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.util.Set;

    public class NIOClient {
        
    /*標識數字*/  
        
    private static int flag = 0;  
        
    /*緩沖區大小*/  
        
    private static int BLOCK = 4096;  
        
    /*接受數據緩沖區*/  
        
    private static ByteBuffer sendBuffer = ByteBuffer.allocate(BLOCK);  
        
    /*發送數據緩沖區*/  
        
    private static ByteBuffer receiveBuffer = ByteBuffer.allocate(BLOCK);  
        
    /*服務器端地址*/  
        
    private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(  
                
    "localhost"8888);  
      
        
    public static void main(String[] args) throws IOException {  
            
    // 打開socket通道  
            SocketChannel clientChannel = SocketChannel.open();  
            
    // 設置為非阻塞方式  
            clientChannel.configureBlocking(false);  
            
    // 打開選擇器  
            Selector selector = Selector.open();  
            
    // 注冊連接服務端socket動作  
            clientChannel.register(selector, SelectionKey.OP_CONNECT);  
            
    // 連接  
            clientChannel.connect(SERVER_ADDRESS);  
        
            SocketChannel socketChannel;
            Set
    <SelectionKey> selectionKeys;    
            String receiveText;  
            String sendText;  
            
    int count=0;  
      
            
    while (true) {  
                
    //選擇一組鍵,其相應的通道已為 I/O 操作準備就緒。  
                
    //監控所有注冊的 channel ,當其中有注冊的 IO 操作可以進行時,該函數返回,并將對應的 SelectionKey 加入 selected-key set 
                selector.select();  
                
    //返回此選擇器的已選擇鍵集。  
                selectionKeys = selector.selectedKeys();  
                
    //System.out.println(selectionKeys.size());  
                for(SelectionKey selectionKey:selectionKeys){ 
                    
    //判斷是否為建立連接的事件
                    if (selectionKey.isConnectable()) {  
                        System.out.println(
    "client connect");  
                        socketChannel 
    = (SocketChannel) selectionKey.channel();  //
                        
    // 判斷此通道上是否正在進行連接操作。  
                        
    // 完成套接字通道的連接過程。  
                        if (socketChannel.isConnectionPending()) { 
                            
    //完成連接的建立(TCP三次握手)
                            socketChannel.finishConnect();  
                            System.out.println(
    "完成連接!");  
                            sendBuffer.clear();  
                            sendBuffer.put(
    "Hello,Server".getBytes());  
                            sendBuffer.flip();  
                            socketChannel.write(sendBuffer);  
                        }  
                        socketChannel.register(selector, SelectionKey.OP_READ);  
                    } 
    else if (selectionKey.isReadable()) {  
                        socketChannel 
    = (SocketChannel) selectionKey.channel();  
                        
    //將緩沖區清空以備下次讀取  
                        receiveBuffer.clear();  
                        
    //讀取服務器發送來的數據到緩沖區中  
                        count=socketChannel.read(receiveBuffer);  
                        
    if(count>0){  
                            receiveText 
    = new String( receiveBuffer.array(),0,count);  
                            System.out.println(
    "客戶端接受服務器端數據--:"+receiveText);  
                            socketChannel.register(selector, SelectionKey.OP_WRITE);  
                        }  
      
                    } 
    else if (selectionKey.isWritable()) {  
                        sendBuffer.clear();  
                        socketChannel 
    = (SocketChannel) selectionKey.channel();  
                        sendText 
    = "message from client--" + (flag++);  
                        sendBuffer.put(sendText.getBytes());  
                         
    //將緩沖區各標志復位,因為向里面put了數據標志被改變要想從中讀取數據發向服務器,就要復位  
                        sendBuffer.flip();  
                        socketChannel.write(sendBuffer);  
                        System.out.println(
    "客戶端向服務器端發送數據--:"+sendText);  
                        socketChannel.register(selector, SelectionKey.OP_READ);  
                    }  
                }  
                selectionKeys.clear();  
            }  
        }  
    }




    posted on 2012-08-09 12:59 abin 閱讀(650) 評論(0)  編輯  收藏

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


    網站導航:
     
    主站蜘蛛池模板: 精品久久久久久国产免费了 | 午夜免费福利网站| 亚洲熟妇无码一区二区三区导航| 免费黄色小视频网站| 亚洲高清免费视频| 亚洲系列中文字幕| 哒哒哒免费视频观看在线www| 中文字幕版免费电影网站| 亚洲国产视频网站| 伊人久久亚洲综合影院| 午夜视频免费在线观看| 亚洲avav天堂av在线网毛片| 久久亚洲综合色一区二区三区| 台湾一级毛片永久免费| www在线观看免费视频| 亚洲免费一级视频| 亚洲综合色自拍一区| 最新中文字幕免费视频| a毛看片免费观看视频| 亚洲一本到无码av中文字幕| 日本亚洲成高清一区二区三区| 久久午夜免费视频| 一个人免费视频观看在线www | 国产成人亚洲精品蜜芽影院| 国产亚洲福利精品一区| 免费黄色一级毛片| 日本在线免费观看| 无遮挡免费一区二区三区| 亚洲免费视频观看| 国产偷v国产偷v亚洲高清| 四虎影永久在线高清免费| 国产91色综合久久免费分享| 久久九九免费高清视频| 色偷偷亚洲第一综合| 亚洲制服丝袜一区二区三区| 亚洲av无码专区国产乱码在线观看 | a级毛片视频免费观看| 国产亚洲视频在线观看网址| 亚洲国产一区在线观看| 久久精品国产亚洲av麻豆| 亚洲无线一二三四区手机|