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);

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