【问题标题】:What is the difference between connection and read timeout for sockets?套接字的连接和读取超时有什么区别?
【发布时间】:2023-03-17 13:22:01
【问题描述】:

3 个问题:

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

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

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

【问题讨论】:

    标签: java sockets timeout connection


    【解决方案1】:
    1. 套接字的连接超时和读取超时有什么区别?

    连接超时是建立初始连接的超时时间;即完成 TCP 连接握手。读取超时是等待读取数据的超时时间1。如果服务器(或网络)在客户端发出套接字read 调用后 秒内未能传递任何数据,则会引发读取超时错误。

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

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

    1. 读取超时设置为“无限”是什么意思?什么情况下可以无限循环?什么可以触发无限循环结束?

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


    1 - 这不是......正如一位评论者所认为的......套接字可以打开或空闲多长时间的超时。

    【讨论】:

      【解决方案2】:

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

      如果该值设置为无穷大,您将不会永远等待。它只是意味着 JVM 没有超时,操作系统将负责所有超时。但是,操作系统的超时时间可能非常长。在一些慢速网络上,我发现超时时间长达 6 分钟。

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

      处理 TCP 超时的唯一安全方法是在不同的线程中运行连接代码,并在时间过长时中断线程。

      【讨论】:

      • "如果该值设置为无穷大,您将不会永远等待。"只要不是讨论“无限”的含义,你肯定会等待很长时间。我们这里有一个案例,其中一个 HttpURLConnection.getResponseCode() 正在为 apprx 挂起。一个星期,直到我们重新开始这个过程。显然 JVM 端没有设置超时,Linux OS 端也没有设置超时。
      • 最后一段不正确。连接最多会在大约一分钟后超时。完全不需要单独的线程。如果没有数据,您当然可以让 reads 永远运行。然而,Javadoc 关于默认连接超时是无限的是错误的。不是。
      • @comeGetSome 这不正确。您可以关闭套接字以进行输入。这将导致被阻止的读取遇到流结束。
      • @comeGetSome:我必须使用一个持有对开放 HTTP URL 连接的引用的线程来实现这一点。当所述线程关闭连接时,另一个线程抛出“java.net.SocketException:Socket closed”。感谢错误 JDK-8075484 让我这样做!
      • @comeGetSome 您当然可以在不牵手的情况下拨打Socket.shutdownInput() 吗?注意这些超时由 TCP 而非 JVM 强制执行。
      猜你喜欢
      • 1970-01-01
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      • 2013-09-05
      • 2018-05-09
      • 2017-10-29
      相关资源
      最近更新 更多