NIO:如果缓冲区

时间:2017-11-27 17:39:24

标签: java nio

我想编写一个NIO Server \ Client应用程序,我希望Server只有在Channel中有数据时才能读取socketChannel。在我的演示应用程序中用于测试目的客户端只是连接到服务器但从未将请求发送到服务器,但我发现 selectionKey.isReadable()始终返回true。我希望因为客户端永远不会发送请求 isReadalble()应该返回false。 我面对 isReadable = true 的问题是它让我的应用程序尝试从socketChannel读取数据,我真的想避免这种情况。 有什么方法可以在套接字通道中读取数据时通知我的服务器? 以下是我的服务器App中的read()方法,其中isReadable()始终返回true:

private void read(SelectionKey selectionKey){    
    if(selectionKey.isReadable()){     
        SocketChannel socketChannel = (SocketChannel)selectionKey.channel();
        ByteBuffer buffer = ByteBuffer.allocate(256);
        try {
            socketChannel.read(buffer);
            String value = new String(buffer.array()).trim();
            System.out.println("Value is: " +value);
        } catch (IOException e) {
            System.out.println("Not able to read");
        }
    }
}

1 个答案:

答案 0 :(得分:2)

  

我想编写一个NIO Server \ Client应用程序,我希望Server只有在Channel中有数据时才能读取socketChannel。

这就是SelectorOP_READ的用途。

  

在我的演示应用程序中用于测试目的客户端只是连接到服务器但从未将请求发送到服务器,但我发现selectionKey.isReadable()始终返回true。

所以它是可读的。

  

我希望因为客户端永远不会发送请求isReadable()应该返回false。

错误。如果对等方已关闭连接,它也会返回true。因此,如果没有数据且通道可读,则对等方必须关闭连接。你忽略了read()的返回值,所以你永远都找不到,所以你永远不会关闭频道,所以它仍然可读。

socketChannel.read(buffer);
String value = new String(buffer.array()).trim();

这应该是:

int count = socketChannel.read(buffer);
if (count == -1)
{
    socketChannel.close();
    return;
}
String value = new String(buffer.array(), 0, buffer.limit());

不需要在自己的协议上调用trim()。如果您不想要空格,请不要发送。