tags:

views:

559

answers:

1

I have read the boost asio reference, gone through the tutorial and looked at some of the examples. Still, I am unable to see how a socket should be torn down:

  1. Should I call close() or is this done by the socket's destructor?
  2. When should I call shutdown()
  3. What are the effects of shutdown()? I am aware that it "Disables sends or receives", but how is this done? What can I expect if I send or receive using the socket after it has been disabled?
  4. Which errors can I expect from close()
+2  A: 

Since this is a multi-question, I'll do my best to answer each part to your satisfaction:

1) It's been my experience with ASIO sockets that the destructor handles closing the socket. However, I've only dealt with TCP sockets. The best way to check this is to simply look at the code for the destructor to see if it does anything that resembles a close. I know that Boost code can be a little tricky to walk through, so it might be easiest to simply create a little sample program that opens a UDP socket and then destructs it. That way you can step through the code in a debugger to follow the logic.

Since the designers of Boost took this into account for TCP sockets, I have a hard time imagining they wouldn't do the same for UDP sockets.

2) Call shutdown() only when you feel it's necessary to prevent any code from performing a future recv and/or send on the socket. It's not typically required, though I've seen it used on TCP sockets to force the socket to send a RST when it is closed (as opposed to the default "graceful" shutdown where pending sends are processed).

3) You can think of sockets as being a two-channel form of communication: one for reading, the other for sending. You can shut down either one independently of the other, and you can continue to use one channel when the other is shut down (i.e. you can still receive after shutting down for send and vice versa). Closing a socket is identical to calling shutdown on both recv and send.

Shutting down for recv simply prevents your code from reading any more data. If you attempt to do so, you will get a socket error. Likewise, if the other side of the connection attempts to send data to you, it will receive an error (sorry to switch to TCP world again, but I believe a RST gets replied back to the sender).

Shutting down for send likewise prevents your code from sending any more data. If memory serves me correctly, this looks identical to what happens when you close a socket (a zero-length packet is sent across to signal the other side that the particular channel has been shut down). Any future attempts to send will return an error.

4) You'll have to check your docs to know for certain. MSDN will give you a pretty good indication, though I don't know that I'd consider it to be authoritative.

Brian
Thanks, I have figured out some of this, but am still unsure whether close() really is called in the socket's destructor. What I really hadn't grok'ed was the close connection between boost asio and traditional network programming. Both your explanation of shutdown() and suggestion to look into msdn socket error codes suggests this. +1
Torleif
Glad I could help :)
Brian