Using boost::asio::ip::tcp::socket::cancel() and socket::close()

11,798

Solution 1

Cancel is useful if you want to stop pending operations without closing down the socket.

Note that the Boost documentation recommends using close for greater portability (from doc page):

... For portable cancellation, consider using one of the following alternatives:

  • Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
  • Use the close() function to simultaneously cancel the outstanding operations and close the socket.

Solution 2

cancel won't close the socket, so use cancel if you intend to continue using the socket object. In particular, if you have code in asynchronous handler methods that references the socket's member functions, you may not want to close the socket until you are guaranteed that your currently executing asynchronous handlers have completed.

cancel doesn't guarantee anything about currently executing asynchronous handlers, it only guarantees (per the boost documentation) that "This function causes all outstanding asynchronous connect, send and receive operations to finish immediately" in the case of the socket::cancel() call, or "This function forces the completion of any pending asynchronous operations on the host resolver" in the case of the resolver::cancel() call. This "completion" means that boost will call your asynchronous handler method, it has no jurisdiction to inject any cancellation logic into your asynchronous handler (not to mention it doesn't know about the handler's implementation to begin with).

I would suggest adding your own logic into your asynchronous handler method to handle the case where the socket/resolver/etc. is canceled. If you are calling the cancel method, then you likely have the ability to communicate this cancellation to the asynchronous handler method.

Share:
11,798
xiao su
Author by

xiao su

I am a software engineer and programming language fan. I like software design.This forum is my favorite because I can get some idea and share my idea to others.

Updated on June 18, 2022

Comments

  • xiao su
    xiao su almost 2 years

    If I use close and not cancel, there are some problems.

    The close function can close the socket, and any outstanding asynchronous operations is stopped by returning boost::asio::error::operation_aborted error.

    Why should I use cancel instead of close?

    I worry if some asynchronous operations is executing, the cancel could not cancel it, yes?

    Like asio::ip::tcp::resolve::cancel, I try many times to cancel the resolve_handler after calling async_resolve, but resolve_handler always returns with no boost::asio::error::operation_aborted error.

    I think resolve_handler is being executed?

    Yes?

  • devyndraen
    devyndraen almost 13 years
    holtavolt is correct, using close() is more portable, but it all depends on what you're trying to do.
  • Sam Miller
    Sam Miller almost 13 years
    Note however the remarks for cancel() also state When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
  • xiao su
    xiao su almost 13 years
    thank you for your help,yes,i create serveral objects to process http request and put these objects into a std::deque,one task coming,pop_front one object from deque to work,when finish push_back the object to deque,when something error during the connection,send or read,i will close the socket,but in connect and read,i set a 20s timeout,when connect timeout,i want to cancel the callback func handle_connect,in this handle_connect_timeout or handle_read_timeout,i am not sure which one to use,cancel or close,but now ,i think the best one for me is close
  • xiao su
    xiao su almost 13 years
    thank you and Sam Miller for help,i understand a little now,thank you