关于c ++:使用boost :: asio :: ip :: tcp :: socket :: cancel()和socket :: close()

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

如果我使用关闭而不是取消,则存在一些问题。

close函数可以关闭套接字,并且通过返回boost::asio::error::operation_aborted错误来停止任何未完成的异步操作。

为什么应使用cancel而不是close

我担心如果正在执行一些异步操作,cancel无法取消它,是吗?

asio::ip::tcp::resolve::cancel一样,我多次尝试在调用async_resolve后取消resolve_handler,但是resolve_handler始终返回且没有boost::asio::error::operation_aborted错误。

我认为resolve_handler正在执行?

是?


cancel不会关闭套接字,因此如果要继续使用套接字对象,请使用cancel。特别是,如果异步处理程序方法中的代码引用了套接字的成员函数,则在确保当前执行的异步处理程序完成之前,您可能不想关闭套接字。

cancel不能保证与当前正在执行的异步处理程序有关,它只能保证(根据boost文档)在发生socket::cancel()调用的情况下,"此函数使所有未完成的异步连接,发送和接收操作立即完成"。 ,或者在resolver::cancel()调用的情况下,"此函数强制完成主机解析器上所有未完成的异步操作"。这种"完成"意味着boost将调用您的异步处理程序方法,它没有权限将任何取消逻辑注入到异步处理程序中(更不用说它不知道从一开始就知道该处理程序的实现)。

我建议将自己的逻辑添加到异步处理程序方法中,以处理socket / resolver / etc等情况。被取消。如果您正在调用cancel方法,则可能可以将此取消通知异步处理程序方法。


如果要在不关闭套接字的情况下停止挂起的操作,则"取消"很有用。

请注意,Boost文档建议使用close以获得更大的可移植性(来自doc页面):

...
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.