Using boost::asio::ip::tcp::socket::cancel() and socket::close()
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.
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, 2022Comments
-
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 returningboost::asio::error::operation_aborted
error.Why should I use
cancel
instead ofclose
?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 theresolve_handler
after callingasync_resolve
, butresolve_handler
always returns with noboost::asio::error::operation_aborted
error.I think
resolve_handler
is being executed?Yes?
-
devyndraen almost 13 yearsholtavolt is correct, using close() is more portable, but it all depends on what you're trying to do.
-
Sam Miller almost 13 yearsNote 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 almost 13 yearsthank 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 almost 13 yearsthank you and Sam Miller for help,i understand a little now,thank you