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

时间:2011-06-22 02:41:11

标签: c++ sockets boost boost-asio

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

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正在执行?

2 个答案:

答案 0 :(得分:6)

如果要在不关闭套接字的情况下停止待处理操作,则取消非常有用。

请注意,Boost documentation建议使用close来提高可移植性(来自doc页面):

  

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

     
      
  • 禁用asio的I / O完成端口   通过定义后端   BOOST_ASIO_DISABLE_IOCP。
  •   
  • 使用   close()函数同时进行   取消未完成的操作和   关闭插座。
  •   

答案 1 :(得分:6)

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

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

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