【问题标题】:HttpUrlConnection how to set SO_KEEPALIVEHttpUrlConnection 如何设置 SO_KEEPALIVE
【发布时间】:2017-08-04 16:35:05
【问题描述】:

有没有办法为 JDK stdlib HttpUrlConnection 设置套接字级别选项(如 SO_KEEPALIVE)?我试图找出一种方法来获取不会成为偶尔“挂起”连接的受害者(这似乎是由于网络数据包丢失而经常发生)。更健壮的 HTTP 客户端。我知道有setReadTimeout 方法,但我试图找到一些东西来推动TCP 流恢复正常,而不是像读取超时那样中止它。或者至少报告连接失败已经发生,而不是在读取时永远挂起。但这也允许读取“随时”返回,前提是连接“仍处于活动状态”。

经过一些检查,对于 C 层和 Java 级别的套接字,SO_KEEPALIVE 的默认值似乎都是“关闭”的。

【问题讨论】:

  • 你结婚使用HttpUrlConnection了吗? Apache 的 HttpClient 可能有你正在寻找的东西。 HttpClient
  • @drelliot 我猜你是对的,请随意将其作为答案,我会接受 :)
  • 对于追随者,是的,其他客户端允许指定 SO_KEEPALIVE(见对话)

标签: java http


【解决方案1】:

这不是基于一个而是基于三个谬误。

  1. SO_KEEPALIVE 并没有“推动 TCP 流恢复正常”,尽管它的名称选择不当。它只是在默认的两小时间隔后检测到死连接。这不是你要找的。​​p>

  2. 读取超时不会中止连接。它抛出一个SocketTimeoutException。连接仍然有效,后续读取可能会成功。

  3. 检测到丢弃的数据包并在 TCP 中重新传输。

使用读取超时。

【讨论】:

  • 我曾希望 SO_KEEPALIVE 是周期性的,并以某种方式提醒对方“我没有收到你的最后一个数据包,请重新发送!”但似乎很少见,对方可能已经切断了连接。话虽这么说,至少发送方会以重置响应来通知“嘿,这个管道坏了!”所以就像你说的那样,在我的场景中设置一个(大)读取超时将“与使用 SO_KEEPALIVE 一样好”。但是,如果我希望很长的读取仍然成功(或避免中间路由器上的活动超时),我仍然可能需要 SO_KEEPALIVE,是吗? :)
  • @rogerdpack 否。SO_KEEPALIVE 不会按照您的想法行事。
  • 是的,看来我最初的希望是“没有根据的”,也许您误读或误解了我的评论?我说我现在看到它没有达到我的预期,但在某些情况下可能仍然有一些效用。干杯!
  • 我读了你的评论“如果我希望很长的阅读仍然成功......我仍然可能想要 SO_KEEPALIVE,是吗?”答案仍然是“不”。
  • OK 是的,我的意思是“如果我想要很长的读取仍然检测到断开的连接”,抱歉误会了,干杯!
猜你喜欢
  • 2014-05-11
  • 1970-01-01
  • 2011-02-17
  • 2010-12-29
  • 2013-02-18
  • 1970-01-01
  • 2019-01-09
相关资源
最近更新 更多