Java:套接字读取超时异常

Posted

技术标签:

【中文标题】Java:套接字读取超时异常【英文标题】:Java: socket read time out exception 【发布时间】:2012-09-06 13:30:11 【问题描述】:

我试图调用一个非常繁重的进程。 它的平均工作时间估计为 9-10 分钟。

当我执行这个过程时,我将超时设置为一个非常大的数字:99999999。

2分钟后,我收到以下错误:

java.net.SocketTimeoutException: 读取超时

我尝试再弄乱它一些,我将超时设置为 3000,并且在预期的 3 秒后,我得到了同样的错误。

您知道为什么socket.setSoTimeout(99999999) 将其设置为最大 120000 吗?

【问题讨论】:

此方法传递给操作系统,因此此方法的行为取决于您的操作系统。您使用的是哪个版本的操作系统? 您是否尝试过发送 keep-alive 消息或让进程在完成后“呼叫”您而不是让套接字长时间打开? 看来操作系统只是拒绝您的值,因为如果它超出范围。我会尝试使用更高的值但不是那么高(您将其设置为超过 27 小时)。例如,3 分钟、5 分钟、10 分钟。 如果你不想超时,我会尽量不设置,而不是设置得很高。 我将它设置为 3 分钟,但 2 分钟后仍然出现异常 【参考方案1】:

我不确定您的应用程序是如何工作的,但请尝试设置无限timeout to the socket

public void setSoTimeout(int timeout)
              throws SocketException

使用指定的超时时间启用/禁用SO_TIMEOUT,以毫秒为单位。将此选项设置为非零超时,与此 Socket 关联的 InputStream 上的 read() 调用将仅阻塞这段时间。如果超时到期,则会引发 java.net.SocketTimeoutException,尽管 Socket 仍然有效。必须在进入阻塞操作之前启用该选项才能生效。超时必须为> 0。超时为零被解释为无限超时。

如果您提供有关电话的更多信息,我可能会改进答案。

【讨论】:

我尝试将超时设置为 0。(这应该是无限时间)但同样,在 120 秒后它会引发异常。 连接时,缓冲区是否读取任何数据?我的意思是,服务器是否响应您的连接?,因为服务器地址有可能在您的网络中未正确解析,我不知道它是本地服务器,还是 ***,或者只是远程服务器,我不知道'不知道该地址是使用 netbios 查询、主机文件还是远程 dns 解析的,有很多元素可能导致错误的地址 服务器是本地的,当我将繁重的进程设置为不到 2 分钟时,它工作得很好。 是否有任何应用程序容器可能会使用默认超时覆盖您的连接超时,例如服务器或客户端中的 Websphere、apache tomcat 或 jboss?如果是这样,你应该检查环境的配置 fer13488,没有任何容器。【参考方案2】:

显然,您并没有设置您认为自己设置的超时时间,或者其他人在之后更改了它。您必须发布一些代码才能进一步阐明。

请注意,根据 TCP/IP Illustrated, Vol II, #17.4 中的 WR Stevens,超时会保持在 1000Hz 滴答数的短时间内,因此超过 11 分钟的超时不会不可能。这适用于 BSD 代码。

【讨论】:

【参考方案3】:

我遇到了同样的问题,但没有使用解决方案 socket.shutdownInput(); socket.shutDownOutput(); 直到最后一次读取或写入数据到套接字。这使套接字进入 FIN_WAIT 状态,因此在关闭前等待 2 分钟。你可以在this post了解更多信息

【讨论】:

这种技术不可能解决读取超时异常。 如果您花时间运行我的测试用例,您会发现这是解决方案。您可以自己尝试,将一些输入写入套接字并使用shutdownInput,您将看到套接字将更改为 FIN_WAIT 状态。等待 2 分钟,您将看到套接字已关闭。 关闭套接字对读取超时没有影响。关闭另一端可能,但发送一些东西也是如此。这没有解决问题:“为什么 socket.setSoTimeout(99999999) 将其设置为 120000 max?” “socket.setSoTimeout(99999999) 将其设置为 120000 max”只是一个副作用。假设您创建了一个套接字并连接到另一端,您可以使用 netstat -na| 查看找到套接字处于 ESTABLISHED 状态的“端口号”。现在发送一些输入并使用shutdownInput,您将看到套接字状态变为CLOSE_WAIT。同样,如果您在我的帖子中运行我的测试用例,您自己也可以看到。 “socket.setSoTimeout(99999999) 将其设置为最大 120000”是 问题。 关闭套接字确实会改变端口状态,并发送一个 FIN,并且导致阅读器出现 EOS 条件,但不会更改读取超时。您无需运行测试用例即可知道这一点。

以上是关于Java:套接字读取超时异常的主要内容,如果未能解决你的问题,请参考以下文章

蓝牙连接错误:“jnius.jnius.JavaException:发生 JVM 异常:读取失败,套接字可能关闭或超时,读取 ret:-1”

java - 如何超时读取Java Socket?

java.io.IOException: 读取失败,套接字可能关闭或超时,在 Android 5.0.1 Lollipop 版本上读取 ret: -1

react-native蓝牙连接失败:java.io.IOException读取失败,套接字可能关闭或超时,读取ret:-1

Java,增加套接字超时

Zebra 打印机连接失败“读取失败,套接字可能关闭或超时,读取 ret:-1”