I'm experimenting with Python's socketserver.TCPServer, to see how it works.
I think I have most things figured out, but the one question that remains is how to detect sudden client disconnects, and if it's even possible.
What I've seen so far is that if I write a simple TCPServer, and connect to it with telnet, once telnet disconnects, the TCPServer knows that the client disconnected. Clearly, it gets a TCP message that tells it the client is disconnecting. That's great.
I went one step further, and instead of closing the telnet process on the client, I sent it a SIGKILL, to kill the process without even letting it clean up (tell the server it's disconnecting). Even then, the server knows that the client left right away. It seems that the OS of the client - not the telnet process - sends the TCP FIN/RST message to tell the server the client is gone. Also great.
Next, I went one step beyond that, and while the telnet client was connected to my TCPServer, I told iptables on the client to stop talking to the server. Now, there was absolutely no message being sent to the server to tell it that the client disappeared. At this point, my TCPServer couldn't tell that the client had left.
I know that I can set a socket.setdefaulttimeout() to stop a recv() from blocking indefinitely waiting for a message from the client. The trouble with that is that the timeout will be triggered if the client just stays quiet for a while (doesn't send the server any messages), or if the client disappears all of a sudden.
So my question is this: when a socket is connected between a server and a client, and the client disappears completely, without sending a TCP FIN or RST, does the server have any way of knowing that the client is gone (as opposed to still there, but not sending any messages)? Or is having some sort of heartbeat that the client would stop responding to the main way to tell that the client is gone?
I read somewhere that TCP has keepalive built into the protocol, but that the normal timeout for that is set by the OS, not adjustable, and is hours, and should not be relied upon.
While I'm currently working with Python, I imagine this is more of a generic networking question than Python-specific.
Update: For anyone interested, this is what I ended up with. There's a few improvements that could be made, like adding if __name__ == "__main__"
, and handling messages longer than 1024 bytes, but as far as letting clients connect, and detecting if they disappear, it seems to work pretty well.