目前我正在研究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)
数据包被发送.
可能是什么问题呢?它可以与客户有关吗?
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'对象,这可能是通道选择键的附件.
归档时间: |
|
查看次数: |
3384 次 |
最近记录: |