我偶尔会遇到 SocketChannel.read()
在非阻塞 channel (RH6 上的 JDK 1.6 变体)上阻塞的情况。我对规范的阅读表明这永远不应该发生。在向套接字添加较长的超时后(我认为这真的没有必要......),我看到以下内容:
java.io.IOException:连接超时
在 sun.nio.ch.FileDispatcherImpl.read0( native 方法)
...
在 sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
...
查看源代码,这只是调用 read()
,它应该不会阻塞在设置了 O_NONBLOCK 的文件描述符上。
(这可能类似于:SocketChannel.read() blocks indefinitely,但是在我的例子中, channel 肯定被配置为非阻塞,并且同步在这里恕我直言真的不重要,因为无论任何其他考虑因素,调用都不应该阻塞.)
我知道非阻塞的 read()
可能会因为分页而阻塞,但是我的套接字超时设置为几分钟,所以分页实际上不是罪魁祸首.
有什么想法吗?
设置代码为:
public void addConnection(SocketChannel channel) throws SocketException {
channel.socket().setTcpNoDelay(true);
channel.socket().setReceiveBufferSize(defReceiveBufferSize);
channel.socket().setSendBufferSize(defSendBufferSize);
channel.socket().setSoTimeout(defSocketReadTimeout);
try {
channel.configureBlocking(false);
} catch (IOException ioe) {
Log.logErrorWarning(ioe);
throw new RuntimeException("Unable to configure non-blocking socket");
...
}
最佳答案
'连接超时'是指网络错误,不是读取超时。
这里没有证据表明读取实际上被阻止了。网络错误已经存在,等待 I/O 操作向其报告。您的 read()
通过抛出此异常立即返回。
在非阻塞套接字 channel 上设置读取超时没有任何意义。
关于java - SocketChannel.read() 在非阻塞 channel 上阻塞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47062519/