Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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

share|improve this question
    
This question would be better on Stack Overflow, where it would be a duplicate of this one: stackoverflow.com/questions/4160347/close-vs-shutdown-socket –  Blrfl Apr 22 '13 at 22:00
    
I debated whether this belonged here or on SO. The link you gave doesn't completely answer my question, which I think is more of a general programming/protocol question than just the specifics of close and shutdown. –  Chap Apr 22 '13 at 22:21
add comment

1 Answer 1

up vote 5 down vote accepted

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 closeing 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).

share|improve this answer
    
Very clear explanation! One question: although I like CLOSE/CLOSE_OK, it sounds as if I (the client) could just issue shutdown(OUTPUT) and wait to receive EOF, while the server, on reading my EOF, could send <final_message> + EOF. Or are there circumstances under which the server could receive EOF without my having intentionally caused it by issuing shutdown or close? –  Chap Apr 22 '13 at 22:17
1  
If the server must be able to tell the difference between a clean client shutdown and a rupture of the connection (think database transaction: a client gracefully disconnecting should cause a COMMIT as the server's last action but a connection rupture should cause a ROLLBACK) then use something explicit in the protocol. If that doesn't matter for your protocol, your idea of just sending shutdown(SHUT_WR) is perfectly fine and will work correctly. –  Celada Apr 22 '13 at 22:35
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.