Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asio end socket functions: cancel, shutdown, close, release

Tags:

c++

boost-asio

Which is the correct way to close and clean up a socket?

I have the io_service running in a secondary thread and I need to close the connection from the main thread:

void closeConnection()
{
    ioc.post([&socket]() {
        // Which ones do I have to call?
        // In what order?
        // What do they do?
        //socket.cancel();
        //socket.shutdown(asio::ip::tcp::socket::shutdown_both);
        //socket.close();
        //socket.release();
    });
    secondaryThread.join();
}

What is the difference between all these functions?

I've tried with this sequence ...

socket.cancel();
socket.close();
socket.release();

and seems to close up the connection without errors but takes too much time (about 5-10 seconds), so I guess I'm doing something wrong.

like image 977
tuket Avatar asked Jul 22 '18 20:07

tuket


1 Answers

I presume you're talking about a graceful close, i.e. read/write any outstanding data, then close the socket.

The proper steps are:

  1. Call shutdown() to indicate that you will not write any more data to the socket.

  2. Continue to (async-) read from the socket until you get either an error or the connection is closed.

  3. Now close() the socket (in the async read handler).

If you don't do this, you may end up closing the connection while the other side is still sending data. This will result in an ungraceful close.


cancel() and release() aren't the calls you use in a normal flow:

  • cancel() cancels all outstanding asynchronous operations.
  • release() releases ownership of the underlying native socket.
like image 178
rustyx Avatar answered Nov 15 '22 07:11

rustyx