Java NIO服务器

Tes*_*tas 6 java nio

目前我正在研究Java NIO Server(单线程)并遇到了一些问题.服务器接受传入连接,将初始数据包(数据包包含客户端用于进一步通信的一些数据)写入客户端但不从中读取.服务器只在我关闭客户端时尝试读取,当然,它返回-1.

在接受连接时,它在以下位置注册:

selectionKey = socketChannel.register(_selector, SelectionKey.OP_READ)
Run Code Online (Sandbox Code Playgroud)

selectionKey.isReadable()回来false(应该吗?)

在发送初始数据包之前,操作更改为:

_selectionKey.interestOps(_selectionKey.interestOps() | SelectionKey.OP_WRITE)
Run Code Online (Sandbox Code Playgroud)

发送初始数据包后,操作更改为:

selectedKey.interestOps(selectedKey.interestOps() & ~SelectionKey.OP_WRITE)
Run Code Online (Sandbox Code Playgroud)

数据包被发送.

可能是什么问题呢?它可以与客户有关吗?

use*_*421 6

selectionKey.isReadable() 返回false(应该吗?)

当然,直到有数据要读或流结束.

在发送初始数据包之前,操作更改为:

_selectionKey.interestOps(_selectionKey.interestOps() | SelectionKey.OP_WRITE)

馊主意.OP_WRITE几乎总是准备就绪,即除了套接字发送缓冲区已满,所以你只会让你的Selector.select()方法无意识地旋转.

当你想写入频道时,只需写.在经典循环中执行此操作:

while (buffer.position() > 0)
{
    buffer.flip();
    int count = channel.write(buffer);
    buffer.compact();
    if (count == 0)
    {
        // see below ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果count是零,你应该注册OP_WRITE,跳出循环,并回到Selector循环.如果你没有发生这种循环,请取消注册 OP_WRITE.

请注意,这意味着每个通道都有一个写缓冲区.出于类似的原因(read()返回零),每个通道还需要一个读缓冲区.这反过来意味着一个包含它们的通道'session'对象,这可能是通道选择键的附件.