收到operation_canceled的完成处理器中发起新异步操作是否合法?
问题解答
核心结论
当完成处理器接收到boost::asio::error::operation_canceled错误时,在同一个I/O对象上发起新的异步操作是语义有效的,无需将该I/O对象视为“无效”。
原因说明
operation_canceled错误仅表示当前触发的异步操作被主动取消(比如调用了socket.cancel()),但I/O对象自身的状态并未被破坏。只要对象处于合法状态(如套接字未关闭、未被销毁),就可以继续发起新的异步操作。
代码验证与说明
你提供的代码中,在第一个async_receive被取消后,在完成处理器内发起第二个async_receive的逻辑完全合法。以下是补充中文注释后的代码:
#include <boost/asio.hpp> #include <iostream> int main() { try { boost::asio::io_context io_context; // 创建UDP套接字并绑定到本地端点 boost::asio::ip::udp::socket socket(io_context); boost::asio::ip::udp::endpoint local_endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 54321); socket.open(boost::asio::ip::udp::v4()); socket.bind(local_endpoint); std::vector<std::uint8_t> buffer(100); socket.async_receive(boost::asio::buffer(buffer.data(), buffer.size()), [&socket, &buffer](boost::system::error_code ec, std::size_t len) { if (!ec) { std::cout << "1: UDP-Server: 接收字节数: " << len << std::endl; } else if (ec == std::errc::operation_canceled) { // 此处语义有效,可正常发起新的异步接收操作 socket.async_receive(boost::asio::buffer(buffer.data(), buffer.size()), [&socket, &buffer](boost::system::error_code ec, std::size_t len) { if (!ec) { std::cout << "2: UDP-Server: 接收字节数: " << len << std::endl; } }); } }); socket.cancel(); // 主动取消第一个异步接收操作 io_context.run(); } catch (std::exception &e) { std::cerr << "意外异常: " << e.what() << std::endl; } return 0; }
关键注意事项
- 只有当I/O对象被关闭(如调用
socket.close())或销毁后,才无法发起新的异步操作,此时会触发boost::asio::error::bad_descriptor类错误。 - 需确保lambda捕获的变量(如
socket、buffer)在新异步操作的生命周期内保持有效,避免悬空引用导致未定义行为。
内容的提问来源于stack exchange,提问作者Degoah
相关产品推荐
相关产品推荐

