使用boost :: asio :: ip :: tcp :: socket :: cancel()和socket :: close()

xia*_* su 3 c++ sockets boost boost-asio

如果我使用close而不取消,则存在一些问题.

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

我为什么要用cancel而不是close?

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

就像asio::ip::tcp::resolve::cancel,我尝试多次取消resolve_handler后调用async_resolve,但resolve_handler总是返回没有boost::asio::error::operation_aborted错误.

我认为resolve_handler正在执行?

是?

hol*_*olt 6

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

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

...对于便携式取消,请考虑使用以下替代方案之一:

  • 通过定义BOOST_ASIO_DISABLE_IOCP禁用ASIO的I/O完成端口后端.
  • 使用close()函数同时取消未完成的操作并关闭套接字.


小智 6

cancel不会关闭套接字,所以cancel如果您打算继续使用套接字对象,请使用.特别是,如果在异步处理程序方法中有代码引用套接字的成员函数,则可能不希望在确保当前正在执行的异步处理程序已完成之前关闭套接字.

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

我建议将自己的逻辑添加到异步处理程序方法中,以处理socket/resolver/etc的情况.被取消了.如果您正在调用cancel方法,那么您可能能够将此取消传递给异步处理程序方法.