Java NIO服务器

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

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

selectionKey = socketChannel.register(_selector, SelectionKey.OP_READ) 

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

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

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

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

 selectedKey.interestOps(selectedKey.interestOps() & ~SelectionKey.OP_WRITE) 

数据包被发送。

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

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 ... } } 

如果count为零,则应注册OP_WRITE ,退出循环,然后返回Selector循环。 如果你没有发生这种循环,请取消注册 OP_WRITE.

请注意,这意味着每个通道都有一个写缓冲区。 由于类似的原因( read()返回零),每个通道也需要一个读缓冲区。 这又意味着一个包含它们的通道“会话”对象,这可能是通道选择键的附件。

OP_WRITE仅在您想要控制滞后的罕见情况下需要,换句话说,当接收器太慢或发送器太快时。