netty系列(三)--nio快速入門

在學習nio入門前,請先學習前一篇文章,理清nio三大組件的關係

圖解關係:

在這裏插入圖片描述
說明:

  • 當客戶端連接時,會通過ServerSocketChannel
    ,得到SocketChannel

  • 將socketChannel註冊到Selector上,並且返回一個
    selectorKey,該SelectorKey會和Selector關聯

  • selector進行監聽select方法,返回有事件發生的通道個數

  • 進一步得到各個SelectKey

  • 再通過SelectKey,反向獲取channel

  • 最後通過channel完成對應的事件

服務端:

  public static void main(String[] args) throws IOException {
        //創建serverSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //創建selector對象
        Selector selector = Selector.open();
        //綁定端口6666,在服務器端監聽
        serverSocketChannel.socket().bind(new InetSocketAddress(6666));
        //設置非阻塞
        serverSocketChannel.configureBlocking(false);
        //把ServerSocketChannel註冊到Selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //循環等待客戶端請求
        while (true) {
            if (selector.select(1000) == 0) {
                System.out.println("服務器等待了1秒,無連接");
                continue;
            }
            //獲取selectorKey集合
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            //遍歷集合
            for (SelectionKey key : selectionKeys) {
                //反向獲取到channel,根據不同事件做出處理
                if (key.isAcceptable()) {//如果是連接請求
                    //給該客戶端生成一個socketChannel
                    SocketChannel channel = serverSocketChannel.accept();
                    //將當前的channel註冊到selector上
                    channel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1024));
                }
                if (key.isReadable()) {//讀的請求
                    //獲取到該channel
                    SocketChannel channel = (SocketChannel) key.channel();
                    //獲取buffer
                    ByteBuffer byteBuffer = (ByteBuffer) key.attachment();
                    channel.read(byteBuffer);
                    System.out.println("from 客戶端" + new String(byteBuffer.array()));

                }
                //最後移出
                selectionKeys.remove(key);
            }
        }
    }

客戶端:

  public static void main(String[] args) throws IOException {
        SocketChannel socketChannel=SocketChannel.open();
        //非阻塞
        socketChannel.configureBlocking(false);
        //提供服務端的ip和端口
        InetSocketAddress address=new InetSocketAddress("127.0.0.1",6666);
        //連接服務器
        if(!socketChannel.connect(address)){
            while(!socketChannel.finishConnect()){
                System.out.println("因爲連接需要事件,可以做其他的事情");
            }
        }else {
            //連接成功了
            String str="hello world";
            ByteBuffer byteBuffer=ByteBuffer.wrap(str.getBytes());
            //將數據寫入channel
            socketChannel.write(byteBuffer);

        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章