java - SocketChannel.read() 在非阻塞 channel 上阻塞

标签 java linux sockets asynchronous nio

我偶尔会遇到 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/

相关文章:

java - 让 Selenium-WebDriver 示例正常工作

java - ReentrantLock如何同步?

Java 不在 JPanel 上绘制

Linux.netcat + 庆典

c - 我的http get数据包格式有什么问题?

winapi - GetAddrInfo无法解析ipv6.google.com(但nslookup可以)

java - Java 正则表达式中 matches() 和 find() 之间的区别

linux - curl 同时下载和上传相同的文件

c++ - 创建崩溃日志

windows - 测试套接字连接的好工具?