12

What exactly does the destructor of boost::asio::ip::tcp::socket do? I can't tell, even after scouring Boost docs and source code, if I need to use

socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both);
socket->close();

before calling

delete socket;

Do I need to close the socket manually, or does the destructor handle this?

owacoder
  • 4,815
  • 20
  • 47
  • Looking at the [source code](http://www.boost.org/doc/libs/1_57_0/boost/asio/basic_stream_socket.hpp) it doesn't seem to have one. – amanuel2 Oct 02 '16 at 01:43
  • I know. It's strange, since it seems like the socket would perform *some* cleanup, but I thought I just hadn't found the right piece of code. – owacoder Oct 02 '16 at 01:45
  • No. It must be the right code since it's straight from boost website unless some strange activity has been going on. But the point is that there is no destructor so you have to shutdown and close the socket your self. Understand? – amanuel2 Oct 02 '16 at 01:48
  • @amanuel2 see my answer. – sehe Oct 02 '16 at 14:42
  • 1
    @amanuel2 All I/O objects defer their cleanup to the [`basic_io_object`](http://www.boost.org/doc/libs/1_61_0/doc/html/boost_asio/reference/basic_io_object/_basic_io_object.html) from which they all derive. – Tanner Sansbury Oct 03 '16 at 02:21
  • You never need to call shutdown 'both' before closing unless you're dealing with a socket which has been inherited that you really really want to close now. – user207421 Oct 03 '16 at 03:23

3 Answers3

9

When a socket is destroyed, it will be closed as-if by socket.close(ec) during the destruction of the socket.

I/O objects, such as socket, derive from basic_io_object. Within the basic_io_object destructor, destroy() will be invoked on the I/O object's I/O service, passing in an instance of the implementation_type on which the I/O object's service will operate. In the case of socket, destroy() will be invoked on a type that fulfills the SocketService type requirement, closing the underlying socket. In the documentation below, a is an instance of a socket service class, and b is an instance of the implementation_type for the socket service class:

a.destroy(b):

[...] Implicitly cancels asynchronous operations, as if by calling a.close(b, ec).

a.close(b, ec):

If a.is_open() is true, causes any outstanding asynchronous operations to complete as soon as possible. Handlers for cancelled operations shall be passed the error code error::operation_aborted.

post: !a.is_open(b).

Tanner Sansbury
  • 51,153
  • 9
  • 112
  • 169
4

No you don't need to close it. Though it might be cleaner to do so, if you want to report any errors surrounding protocol shutdown.

The destructor just /appears/ to be empty, that's a good sign of Modern C++:

sehe
  • 374,641
  • 47
  • 450
  • 633
  • Yes he has to manually close the socket connections manually. and implement the "Destructor" himself. nice answer. – amanuel2 Oct 02 '16 at 15:02
  • 1
    @sehe - Does the destructor cleanly disconnect, performing the two calls in question? Or does it just abruptly close the connection? – owacoder Oct 02 '16 at 17:29
  • 2
    @amanuel2 No, he doesn't have to manually close the socket connection *or* implement the destructor himself. Pointless comment. – user207421 Oct 03 '16 at 04:01
  • @EJP yes he does have to manually close socket as so `socket->shutdown(boost::asio::ip::tcp::socket::shutdown_both); socket->close();` – amanuel2 Oct 03 '16 at 04:05
  • 2
    @amanuel, if you are observing that the socket's destructor does not close the underlying native socket, then please submit a bug report against Asio. Per the documentation and implementation, the native socket should be closed during destruction of the socket. – Tanner Sansbury Oct 03 '16 at 14:50
4

The answers have skipped over the issue of shutdown(). From the close() documentation, "For portable behaviour with respect to graceful closure of a connected socket, call shutdown() before closing the socket".

If deleting the socket does an implicit close, it seems that a call to shutdown() is still recommended before deleting it.

edj
  • 523
  • 7
  • 17