如何在 Linux 上查看/更改套接字连接超时时间?

11
创建 Java Socket 时:
new Socket(host, port);

Socket构造函数在返回之前会尝试连接host:port。在Windows上,对于无法到达的主机,这几乎立即失败,但对于Linux来说,Socket超时可能需要长达5分钟。

我知道如果我有控制创建Socket的权限,我可以执行以下操作:

Socket s = new Socket();
s.bind(..);
s.connect(.., timeout);

但我宁愿让操作系统使用合理的默认值。在Linux上有没有改变这个设置的方法?


我认为最好在每个应用程序的基础上配置超时时间。否则,所有在此计算机上运行的其他应用程序都将受到此设置的影响。 - Reginaldo
1
同意,如果我想要更改设置,我仍然想知道它是什么。 - Kevin
1
如果您坚持更改操作系统设置,那么我认为这不再是一个与编程相关的问题,而应该属于服务器故障。 - akarnokd
4个回答

14

我认为你想要的是 /proc/sys/net/ipv4/tcp_syn_retries。默认值通常为5或6,大约需要3分钟。

请注意,这些是全局设置。


重试之间的时间是如何设置的?它似乎随着每次重试而呈指数增长。这是在哪里设置的? - Kevin
时间间隔确实会增加,至少在某个程度上是这样。我的记忆有些模糊了。我不记得这是BSD的事情还是TCP的事情,而且我也不确定Linux是否提供了一种控制它的方法。 - Duck
6
间隔时间由名为rtoMin、rtoMax和rtoInitial的值控制,其中rto代表往返超时时间。基本上,它表示一个数据包完成一次往返所需的时间。因此,如果TCP发送第一个消息,它会等待rtoInitial时间。如果未能收到响应,则会将rto加倍(并添加一些抖动值),然后再次尝试。这将持续进行直到达到最大重试次数。当前的rto值永远不会超过rtoMax。 - Aditya Sehgal
@Aditya 感谢澄清。我记不清TCP算法是在连接阶段发挥作用还是操作系统设置任意计时器。 - Duck
@Duck 我已经在应用程序级别为我的SOAP客户端设置了连接超时和读取超时。这在Windows上运行良好,但是在Linux上超时值不起作用。你能帮我解决这个问题吗? https://stackoverflow.com/questions/47861767/http-connect-timeout-and-read-timeout-for-urlstreamhandler-with-saaj-working-fo - Parul Chauhan

5
我建议不要更改操作系统设置,因为这可能会意外影响其他应用程序。 Socket.setSoTimeout() 方法也可能对你有所帮助。

2
我可以问一下你的踩票原因吗?这样我就能从中学习了。 - akarnokd
2
我认为SO_TIMEOUT适用于读取但不适用于连接,这可能就是原因。不过目前我似乎找不到它的验证信息。 - Samuel Edwin Ward

2

顺便提一下,Linux和Windows在这里表现不完全相同并不完全正确。除了初始的SYN重试(可以在Linux和Windows上配置)外,邻居状态以及其他路由器发送的RST数据包也起到了作用。

如果在Windows上连接尝试立即失败,很可能是被路由器拒绝或者在ARP层面上无法识别邻居。可以尝试使用arp -a -v命令在Windows上查看被拒绝的无法到达的主机。

对于Linux系统,可以使用ip neigh列出本地网络中各个站点的可达性状态。


0

据我所知,这取决于系统的TCP/IP默认超时时间(默认为240秒?)... 一种选择是尝试调整这些值,但这可能会影响同一台机器上依赖超时值的任何其他程序。在这种情况下,更安全的做法可能是在Java connect()调用中降低“超时”值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接