I’m rolling my own application protocol on top of TCP. I’m using Linux and C. I’m wondering whether there is an advisable sequence to closing a socket connection.
The client will always initiate the close by sending a specially-formed string; say, “CLOSE”. I’d like to receive some kind of acknowledgement from the server that it has seen my CLOSE request, so perhaps it needs to send back a special string like “CLOSE_OK”.
I’ve also seen both the close() and shutdown() system calls, but am not sure how to use them. For instance, should the client, after receiving “CLOSE_OK”, do a shutdown(OUTPUT) and then wait to receive a zero-length string? And should the server, after sending “CLOSE_OK”, issue close() and then consider the socket to be dead?
I’m hoping there’s a “best practice” on this subject that I haven’t found yet…
Thanks,
Chap
2
If you need to handshake at the application layer (for instance, in order to get a confirmation from the other end that some persistent data has been committed), do that using your CLOSE
and CLOSE_OK
protocol messages. Indeed you need to do this at the application layer (see the end-to-end principle). But after both ends of the socket are already in agreement that the connection, don’t waste any time or effort gracefully closing one direction of communication, verifying that that happened, and then gracefully closing the other end. Just close()
the socket from both ends. Depending on the timing, the TCP FIN
and ACK
sequences may or may not occur sequentially or cross each other on the wire, but your application shouldn’t care about that. In any case, just close
ing will be the fastest thing you can do.
shutdown
is useful in cases where you really do need to signal that communication has finished in one direction but the other direction is still needed. It can be used, for example, by a client that is talking to a server that will not send any reply until it gets all of the data from the client, complete with an EOF at the end. shutdown(SHUT_WR)
makes that EOF happen without having to close the whole socket (bidirectionally).
2