【问题标题】:Using boost::asio::ip::tcp::socket::cancel() and socket::close()使用 boost::asio::ip::tcp::socket::cancel() 和 socket::close()
【发布时间】:2011-06-22 02:41:10
【问题描述】:

如果我使用close而不是cancel,会有一些问题。

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

是吗?

【问题讨论】:

    标签: c++ sockets boost boost-asio


    【解决方案1】:

    如果您想在不关闭套接字的情况下停止挂起的操作,“取消”很有用。

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

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

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

    【讨论】:

    • 请注意,cancel() 的注释也说明了 在 Windows Vista、Windows Server 2008 和更高版本上运行时,始终使用 CancelIoEx 函数。该功能不存在上述问题。
    • 谢谢你和山姆·米勒的帮助,我现在有点明白了,谢谢
    【解决方案2】:

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

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

    我建议将您自己的逻辑添加到您的异步处理程序方法中,以处理套接字/解析器/等。被取消。如果您正在调用取消方法,那么您可能有能力将此取消传达给异步处理程序方法。

    【讨论】:

    • holtavolt 是正确的,使用 close() 更便携,但这完全取决于您要做什么。
    • 感谢您的帮助,是的,我创建了多个对象来处理 http 请求并将这些对象放入 std::deque,一个任务来了,pop_front 一个对象从 deque 开始工作,当完成 push_back deque 的对象,当连接过程中出现错误,发送或读取时,我将关闭套接字,但在连接和读取中,我设置了 20 秒超时,当连接超时时,我想取消回调函数句柄连接,在这个句柄连接超时或handle_read_timeout,我不确定要使用哪个,取消或关闭,但现在,我认为对我来说最好的一个是关闭
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多