views:

48

answers:

3

Which socket, the clientSocket = accept() or the listen(socket), do you setsockopt SO_KEEPALIVE on to get the connection to clients not to drop?

+2  A: 

Setting the option on each accepted socket would seem most reliable and portable. Inheritance of non-blocking mode across accept is inconsistent across implementations, and SO_KEEPALIVE has no meaning for the listening socket.

jilles
Thank you muchly. I'll wait for some agreement before marking this solved, but your explanation makes the answer seem obvious. Again, thank you! :)
CS Student
@cs student: you do not have to wait for anything (though I +ed jilles response), simply check the `man accept` on your system and accept description in POSIX. IIRC the inheritance of some flags from listen socket is an old BSD trick now mostly deprecated.
Dummy00001
I keep seeing others set it on the bind socket in Windows code. Is it even possible to set it on the accepted socket? If so, where is some "official" example code for winsock for this?
CS Student
A: 

SO_KEEPALIVE can only work on connected TCP socket (since it requires a packet being sent on a timer), which listening socket is not.

Note that this option will not keep the connection from dropping (aside from some broken firewalls that remove states after period of connection inactivity.) Stevens even called it "notify when dead" instead.

Take a look at this HOWTO document for more details.

Nikolai N Fetissov
A: 

From the man page:

If the SO_KEEPALIVE socket option is enabled on an established TCP connection and the connection has been idle for two hours, TCP sends a packet to the remote socket, expecting the remote TCP to acknowledge that the connection is still active. If the remote TCP does not respond in a timely manner, TCP continues to send keepalive packets according to its normal retransmission algorithm. If the remote TCP does not respond within a particular time limit, TCP drops the connection. The next socket system call (for example, recv()) returns an error, and errno is set to ETIMEDOUT.

See getsockopt(2) for details on enabling SO_KEEPALIVE.`

After an idle period with a peer in which no communication has occurred, a probe (small packet) will be sent to the remote peer in order to test if the peer is still alive or not.

If the peer is still available, an ACK message will be received, so it can be deduced that the link is still on. If not, the peer died (actually it's a little bit more complicated because TCP will do some retries before giving up).

You can set up the option both on the client and the server (this means that both the server and the client will be notified of netowrk problems). In any case, on the server you will set the option on the socket returned by accept().

the_void