Java,增加套接字超时

Posted

技术标签:

【中文标题】Java,增加套接字超时【英文标题】:Java, increase the socket timeout 【发布时间】:2011-12-18 14:03:06 【问题描述】:

我有一个简单的服务器客户端应用程序。一切正常,但在某些阶段需要超过 5 分钟才能从服务器获得响应(这是正常的,需要这样)。问题是,如果需要超过 5 分钟,我会不断收到此异常:java.net.SocketTimeoutException: Read timed out

所以我想知道 Windows 或 Java 虚拟机上是否有一些默认套接字超时,我可以设置吗?我无法更改客户端代码,所以setSoTimeout() 不适合我。

使用 Windows XP..

编辑:据我所知,套接字连接未在客户端打开。它从服务器传递。所以我反编译了所有服务器jar文件。但仍然找不到有关超时的任何信息。

【问题讨论】:

检查是否使用系统属性配置了超时。 @HannoBinder,你能解释一下你所说的系统属性是什么意思吗? 我的意思是像sun.net.client.defaultReadTimeout,或者任何可能适用于您客户的连接方式的东西。 套接字超时由客户端设置。 '客户端未打开套接字连接。它从服务器传递的'是不正确的。 【参考方案1】:

默认套接字超时为 0,这意味着永远不会超时。如果 5 分钟后实际超时,则表示已在代码中设置。如果源不可用,并且没有配置,您可以尝试反编译该类,并查找 setSoTimeout 调用。

由于 cmets 以及搜索未找到任何 setSoTimeout() 调用的事实,您可以采取不同的方法。让它超时,然后编写一个小脚本,以防万一。如果你可以从命令行调用你的客户端,你可以解析输出,如果它继续 stderr。

【讨论】:

我反编译并寻找setSoTimeout 调用,但没有找到任何东西。那么它必须设置在其他地方吗? @hs2d 我认为它使用了 int field 0 的默认值【参考方案2】:

在没有任何流量的情况下长时间保持未使用的 TCP 连接打开并不是那么简单。许多防火墙/路由器会在超时后关闭未使用的端口。

一种选择可能是实现简单的keepalive协议以不时发送虚拟数据包,但如果您无法触及客户端代码,这可能不是一种选择。

编辑:我不知道有什么方法可以覆盖客户端代码中设置的 setSoTimeout()。

【讨论】:

@benez 我不同意。如果路由器认为连接是一种宝贵的资源,以至于它会超时,那么您就没有任何业务可以诱使它保持打开状态。无论如何,您仍然必须处理连接丢失。添加 keepalive ping 真的只是一种无意义的痛苦。 @EJP 我还没有看到处理连接丢失的正确实现。在某些情况下,您正在等待实时更新,并且需要两方不断连接以保持他们的数据同步。连接丢失不能简单地通过简单的重新连接来处理。您会错过重要信息或迟到。例如股票市场总是发送心跳,而 IRC 协议要求您用 pong 来回答 ping。是的,您必须处理连接丢失,但您可能希望在某些程序中避免它们。 @EJP 添加心跳至关重要。想象一下下面的场景:在闲置一段时间后,其中一台计算机出现了电源故障。通过完全断开连接,TCP/IP 协议会通知对方这一点,但相比之下,当其中一台计算机发生电源故障时,当然没有人会收到有关它的通知。这不会被自动检测到。在这种情况下,根据另一台计算机的说法,连接仍然建立,一切似乎都很好。只有当客户端尝试实际发送某些内容时,它才会检测到问题。【参考方案3】:

回答 0 是默认超时是不完全正确的。因为例如 Axis2 客户端有默认的 60 秒超时,所以这将取决于你使用什么样的实现来进行调用。

你能提供更多细节吗?很抱歉在答案部分写,但我没有足够的声誉来做 cmets :)

【讨论】:

看这里的代码我只能看到java.io.InputStream。所以必须从服务器到客户端的连接? 嗯,是的,对于 Java,默认值是无限的,但库可能会改变它。也许是一个提示,hs2d,你有没有包含任何罐子?或者,您可以采取不同的方法,让它超时并在失败时重试。【参考方案4】:

你需要保持连接吗?您为什么不重新考虑它以使其更加异步。该架构根本没有扩展。在某一时刻,您的所有可用线程可能都在等待来自服务器的长时间响应。

【讨论】:

如果他想从中读取,他需要保持连接处于活动状态。不能把这一切搞清楚。

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

Java:套接字读取超时异常

Java:如何使用“资源尝试”设置套接字超时

Internet 上的 Java 套接字:ConnectException(操作超时)

java.sql.SQLException:Io 异常:套接字读取超时与关闭连接

java网络编程

java - 如何超时读取Java Socket?