【发布时间】:2012-08-17 01:57:01
【问题描述】:
假设我们有向 Selector 注册的 SocketChannel(处于非阻塞模式)以供阅读。假设在 select() 选择器告诉我们该通道已准备好读取并且我们有一些 ByteBuffer 之后。我们想从我们的通道读取一些字节到这个缓冲区(ByteBuffer 在读取之前被清除)。为此,我们使用通道的 read() 方法返回实际读取的字节数。让我们假设这个数字在从通道读取后是正数,并且 ByteBuffer 的方法 hasRemaining() 返回 true。在这种情况下立即尝试从同一频道读取更多内容是否可行? write() 同样的问题。如果 write() 返回正值并且缓冲区的所有内容都没有发送,是否可以立即重试直到 write() 返回零?
【问题讨论】:
-
只要你处于非阻塞状态,你应该读/写直到返回值为
<= 0,这意味着它会阻塞或结束流。顺便说一句,您的频道通常会准备好写入,因此您应该避免使用写入兴趣,因为它会使您的select循环旋转。仅当SocketChannel.write在完成写入数据之前阻塞时才对写入准备感兴趣。 -
@veer 是的,我忘了说这一切都是关于非阻塞模式的。
-
但是直到返回值 0 但未能完全填满我们的缓冲区,是否真的值得再次尝试立即读取?下一个 read() 返回正值的可能性是否很大?或者正返回值和未完全填充的缓冲区表明我们(很可能)耗尽了内部套接字缓冲区并且应该返回选择?
-
呃……我想你不明白这里发生了什么。
ByteBuffer.hasRemaining表示您还有空间来填充缓冲区。read是否填充您的缓冲区与从套接字读取所有可用数据不同。 -
@veer 是的,不一样。但正如我怀疑的那样,未能完全填充缓冲区的最可能原因是当前没有更多可用数据可从套接字读取(并且新数据将在“长时间”后可用,因此我们应该返回选择)。我很想知道这在实践中是否真的如此。如果是真的,我们可以更早地停止我们的读取循环并执行更少的 read() 调用(不等待