套接字的连接和读取超时之间有什么区别?


180

3个问题:

  1. 套接字的连接读取超时之间有什么区别?

  2. 什么连接超时设置为“无限”是什么意思?在什么情况下可以保持不定式循环?什么会触发无限循环死亡?

  3. 什么超时设置为“无限”是什么意思?在什么情况下可以保持不定式循环?什么会触发无限循环死亡?

Answers:


227

1)套接字的连接和读取超时有什么区别?

连接超时是建立初始连接的超时;即完成TCP连接握手。读取超时是等待读取数据1的超时。具体来说,如果服务器未能在最后一个字节之后发送字节<timeout>秒,则将引发读取超时错误。

2)连接超时设置为“无限”是什么意思?在什么情况下可以保持不定式循环?什么会触发无限循环死亡?

这意味着连接尝试可能永远阻塞。没有无限循环,但是可以通过关闭套接字的另一个线程来阻止尝试连接。(Thread.interrupt()电话也可以解决问题……不确定。)

3)读取超时设置为“无限”是什么意思?它在什么情况下可以保持无限循环?什么会触发无限循环结束?

这意味着read对套接字流的调用可能永远阻塞。再一次没有无限循环,但是read可以通过Thread.interrupt()调用,关闭套接字以及(当然)另一端发送数据或关闭连接来解除阻塞。


1-不是……正如一个评论者所认为的那样……套接字可以打开或空闲多长时间。


8

这些是JVM强制的超时值,用于建立TCP连接并等待从套接字读取数据。

如果该值设置为无穷大,则不会永远等待。这只是意味着JVM没有超时,操作系统将负责所有超时。但是,OS上的超时可能真的很长。在某些速度较慢的网络上,我看到超时时间长达6分钟。

即使您为套接字设置了超时值,如果超时在本地代码中发生,它也可能不起作用。通过连接到被防火墙阻止的主机或拔下交换机上的电缆,我们可以在Linux上重现该问题。

处理TCP超时的唯一安全方法是在另一个线程中运行连接代码,并在花费太长时间时中断该线程。


“如果将该值设置为无穷大,则不会永远等待。” 只要不是要讨论“无穷大”的含义,就可以肯定会等待很长时间。我们在这里有一个案例,其中一个HttpURLConnection.getResponseCode()正在挂约。一周,直到我们重新开始该过程。显然,JVM端没有设置超时,Linux OS端也没有超时。
汤姆·芬克

最后一段不正确。连接最多将在大约一分钟后超时。完全不需要单独的线程。如果没有数据,您当然可以永久运行读取。但是,Javadoc错误地认为默认连接超时是无限的。不是。
洛恩侯爵,

1
@comeGetSome这是不正确的。您可以关闭套接字进行输入。这将导致被阻止的读取遇到流的结尾。
罗恩侯爵,

@comeGetSome:我必须使用一个线程来实现此目的,该线程持有对打开的HTTP URL连接的引用。当所述线程关闭连接时,另一个线程抛出“ java.net.SocketException:套接字关闭”。感谢Bug JDK-8075484使我做到了!
fmcato

@comeGetSome当然可以Socket.shutdownInput()握住您的手机进行通话吗?注意:这些超时是由TCP(而非JVM)强制执行的。
罗恩侯爵
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.