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

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


    網站導航:
     
    主站蜘蛛池模板: 亚洲日韩涩涩成人午夜私人影院| 香蕉视频在线观看免费| 国产亚洲精品资在线| 久久精品网站免费观看| 精品一区二区三区免费| 日本永久免费a∨在线视频| 午夜在线a亚洲v天堂网2019| 亚洲福利视频一区| 亚洲熟妇中文字幕五十中出| 四虎影视精品永久免费| 成人免费毛片观看| 综合在线免费视频| 91精品导航在线网址免费| 最近免费中文字幕中文高清| 阿v视频免费在线观看| 亚洲av日韩精品久久久久久a| 亚洲精品中文字幕无乱码麻豆| 噜噜噜亚洲色成人网站∨| 亚洲欧洲一区二区| 亚洲国产精品久久久天堂| 国产精品亚洲精品日韩已方| 亚洲第一区精品日韩在线播放| 国产在线观看免费完整版中文版| 成人au免费视频影院| 啦啦啦高清视频在线观看免费| 真人做人试看60分钟免费视频| 91免费福利精品国产| 1000部禁片黄的免费看| 91精品视频在线免费观看| 91福利视频免费观看| 国产精品成人观看视频免费 | 成年人在线免费观看| 日韩精品无码区免费专区 | 亚洲av永久无码精品古装片| 亚洲精品成人片在线播放 | 99精品免费视品| 在线观看免费黄网站| 成人电影在线免费观看| 午夜视频在线免费观看| 免费观看无遮挡www的视频| 老司机在线免费视频|