0

Is there any way to set socket level options (like SO_KEEPALIVE) for a JDK stdlib HttpUrlConnection? I'm trying to figure out a way to GET HTTP requests that doesn't fall victim to occasional "hanging" connections (which seem to occur because of network packet loss every so often). A more robust HTTP client. I know there is the setReadTimeout method but I am trying to find something to nudge the TCP stream back into life, instead of just aborting it, as the read timeout seems to. Or at least report that the connection failure has occurred instead of hanging forever on a read. But that also allows the read to come back "whenever it wants to" assuming the connection is "still active."

With some examination it appears that the default for SO_KEEPALIVE is "off" for both the C layer and Java level sockets.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
  • 1
    Are you married to the use of HttpUrlConnection? Apache's HttpClient probably has what you're looking for. [HttpClient](https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/) – drelliot Aug 04 '17 at 16:46
  • @drelliot I'm guessing you're right, feel free to make it an answer and I'll accept it :) – rogerdpack Aug 05 '17 at 19:16
  • for followers, yes other clients allow specifying SO_KEEPALIVE (see conversation) – rogerdpack Apr 01 '18 at 03:02

1 Answers1

2

This is founded on not one but three fallacies.

  1. SO_KEEPALIVE doesn't 'nudge the TCP stream back into life', despite its poorly chosen name. It just detects dead connections, after a default interval of two hours. It isn't what you're looking for.

  2. A read timeout doesn't abort the connection. It throws a SocketTimeoutException. The connection is still alive, and a subsequent read may succeed.

  3. Dropped packets are detected and retransmitted in TCP.

Use a read timeout.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I had hoped that SO_KEEPALIVE would be periodic and somehow alert the other side "I didn't get your last packet, resend it!" but seems it's so infrequent that the other side will have probably already severed the connection. That being said at least the sending side would respond with a reset to notify "hey, this pipe is broken!" So like you said setting a (large) read timeout would be "as good as using SO_KEEPALIVE" for my scenario. However if I wanted very-long reads to still succeed (or avoid liveness timeouts on intermediate routers) I still might want SO_KEEPALIVE, yes? :) – rogerdpack Jan 02 '18 at 21:28
  • @rogerdpack No. SO_KEEPALIVE does not do what you think. – user207421 Jan 02 '18 at 22:30
  • Yes appears my initial hope was "ill founded" as it were, perhaps you mis-read or misunderstood my comment? I was saying I see now that it doesn't do what I hoped, but may still have some utility elsewise in certain circumstances. Cheers! – rogerdpack Jan 02 '18 at 22:41
  • I read your comment 'if I wanted very-long reads to still succeed ... I still might want SO_KEEPALIVE, yes?' and the answer is still 'no'. – user207421 Jan 02 '18 at 23:13
  • OK yeah for that one I meant "if I wanted very-long reads to still detect dropped connections" sorry misspoke on that one, cheers! – rogerdpack Jan 02 '18 at 23:18