首页 > 解决方案 > 是否需要注册兴趣才能写入 NIO 套接字以发送数据?

问题描述

是否需要注册兴趣才能写入 NIO 客户端套接字通道以发送数据?socketChannel.register(selector, SelectionKey.OP_WRITE)在写信给客户之前,我是否必须总是打电话或类似的电话SocketChannel才能在那里写信?

仅仅在客户端线程中将数据写入客户SocketChannelchannel.write(outputBuffer)并唤醒可能阻塞还不够吗?Selector主选择器循环将如下所示:

Selector selector = SelectorProvider.provider().openSelector();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);

while (selector.select() > 0) {  
    Set<SelectionKey> readyKeys = selector.selectedKeys();
    Iterator<SelectionKey> keyIterator = readyKeys.iterator();

    while (keyIterator.hasNext()) {
        SelectionKey key = (SelectionKey)keyIterator.next();
        keyIterator.remove();
        while (keyIterator.hasNext()) {
           ...
           if (key.isAcceptable()) {
               ...
               SocketChannel socketChannel = serverSocketChannel.accept();
               socketChannel.configureBlocking(false);
               socketChannel.register(selector, SelectionKey.OP_READ);
               // client socket channel would be permanently in the read mode
               ...
           } else if (key.isReadable()) {
               ...
           } else if (key.isWritable()) { 
               // the key should know here that the underlying channel
               // has something to be send to the wire, so it should get 
               // here if there are still data to be sent
               socketChannel.write(outputBuffer)
           }

只有当还有一些东西要发送时,它才会到达分支,即来自初始调用if (key.isWritable())的剩余数据;channel.write(outputBuffer)就像当消息太长并且需要发送成块并且我不想阻塞时一样。循环将旋转直到outputBuffer.hasRemaining()是 finally false

我什至在想,是否必须写入 Channel,即发送数据,通过 Selector 完成?只留下传入流量由 Selector 处理,因为只有传入流量需要等待状态?

更新

通过进一步阅读有价值的user207421帖子,我部分地启发了我发布这个问题,NIO Javadoc,在推动加入点的过程中,我总结了这一点:

标签: javasocketsniochannel

解决方案


推荐阅读