SocketChannel.read()在非阻塞通道上阻塞

时间:2017-11-01 19:44:02

标签: java linux sockets asynchronous nio

我偶尔遇到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");
   ...
}

1 个答案:

答案 0 :(得分:3)

'连接超时'表示网络错误,而不是读取超时。

这里没有证据表明读取实际上已被阻止。网络错误已经存在,等待I / O操作报告。抛出此异常后立即返回read()

在非阻塞套接字通道上设置读取超时没有任何意义。