Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you correctly close sockets in boost::asio?

I am trying to wrap my head around resource management in boost::asio. I am seeing callbacks called after the corresponding sockets are already destroyed. A good example of this is in the boost::asio official example: http://www.boost.org/doc/libs/1_60_0/doc/html/boost_asio/example/cpp11/chat/chat_client.cpp

I am particularly concerned with the close method:

void close()
{
   io_service_.post([this]() { socket_.close(); });
}

If you call this function and afterwards destruct chat_client instance that holds socket_, socket_ will be destructed before the close method is called on it. Also any pending async_* callbacks can be called after the chat_client has been destroyed.

How would you correctly handle this?

like image 912
Julian Stecklina Avatar asked Feb 14 '16 14:02

Julian Stecklina


Video Answer


1 Answers

You can do socket_.close(); almost any time you want, but you should keep in mind some moments:

  • If you have threads, this call should be wrapped with strand or you can crash. See boost strand documentation.
  • Whenever you do close keep in mind that io_service can already have queued handlers. And they will be called anyway with old state/error code.
  • close can throw an exception.
  • close does NOT includes ip::tcp::socket destruction. It just closes the system socket.
  • You must manage object lifetime yourself to ensure objects will be destroyed only when there is no more handlers. Usually this is done with enable_shared_from_this on your Connection or socket object.
like image 138
PSIAlt Avatar answered Sep 17 '22 23:09

PSIAlt