【问题标题】:Java: socket read time out exceptionJava:套接字读取超时异常
【发布时间】: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 分钟后仍然出现异常

标签: java sockets exception timeout


【解决方案1】:

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

public void setSoTimeout(int timeout)
              throws SocketException

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

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

【讨论】:

  • 我尝试将超时设置为 0。(这应该是无限时间)但同样,在 120 秒后它会引发异常。
  • 连接时,缓冲区是否读取任何数据?我的意思是,服务器是否响应您的连接?,因为服务器地址有可能在您的网络中未正确解析,我不知道它是本地服务器,还是 vpn,或者只是远程服务器,我不知道'不知道该地址是使用 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 条件,但不会更改读取超时。您无需运行测试用例即可知道这一点。
    猜你喜欢
    • 2012-10-24
    • 2017-03-19
    • 1970-01-01
    • 2013-05-16
    • 2019-10-21
    • 2011-10-03
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多