I\'ve encountered a strange bug with TCP sockets. It seems that SO_KEEPALIVE
is enabled on all sockets by default.
I wrote a short test case to create a
Firstly run your test on a clean installation of the operating system on a VM. I suspect that something else you have installed has fiddled with the keep alive setting, perhaps.
Secondly, I doubt that keep alive being enabled is the cause of your problem. If keep alive wasn't enabled then you would never have got a connection closure notification from that pending read. TCP is supposed to work like that, it allows for intermediate routers to go away and come back and you to neither know nor care. The only time you will be informed of the failure is if you try and send and the connection is broken (or, in this case, if you try and send and the server has bounced). The fact that keep alive was enabled means that at that 1hr 59mins mark the TCP stack transmitted the keep alive and noticed that the connection was down. If keep alive wasn't enabled then you would have had to wait until YOU transmitted something.
If your clients need to know if the connection goes down then it's better to ignore keep alive completely (as you can see, it affects the whole machine even when you're not the person that enabled it and to me that makes it a poor solution). If you can, add an application level ping and/or timeout to your protocol. So, perhaps, every command expects a response within 30secs and you send a from the server every minute... You'll then find out about dead connection as quickly as you like and you can disconnect and reconnect at that point.
I've used this pretty well with my server framework; in fact I have a standard 'async read timeout' connection filter and a 'connection re-establishment' filter which make it trivial to ensure that the connections are always live. All the read timeout does is abort the existing connection and the connection re-establishment code kicks in to recreate the connection just as it would if the connection had been closed for any other reason.