我偶尔遇到SocketChannel.read()
阻塞非阻塞通道(RH6上的JDK 1.6变体)的情况。我对规范的解读说,这绝不应该发生。在套接字上添加一个大的超时(我认为不应该真的需要......)后,我看到以下内容:
java.io.IOException: Connection timed out
at sun.nio.ch.FileDispatcherImpl.read0(Native method)
...
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
...
查看源代码,这只是调用read()
,这可能不应该阻塞设置了O_NONBLOCK的文件描述符。
(这可能类似于:SocketChannel.read() blocks indefinitely,但是在我的情况下,频道肯定被配置为非阻塞,并且同步在这里真的应该无关紧要,因为呼叫不应该阻塞而不管任何其他考虑因素。)
我知道非阻塞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");
...
}
答案 0 :(得分:3)
'连接超时'表示网络错误,而不是读取超时。
这里没有证据表明读取实际上已被阻止。网络错误已经存在,等待I / O操作报告。抛出此异常后立即返回read()
。
在非阻塞套接字通道上设置读取超时没有任何意义。