C++ 使用asio协程搭建异步服务器的过程
协程核心定义协程是用户态轻量级执行单元能在执行中主动暂停挂起并保留上下文待条件满足后恢复执行切换开销远低于线程在你的Boost.Asio代码中协程通过co_await等待异步IO如读取客户端数据挂起时不阻塞线程IO完成后自动恢复让异步代码像同步代码一样易读。实现123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687#include iostream// 引入Boost.Asio协程相关头文件#includeboost/asio/co_spawn.hpp // 协程创建函数#includeboost/asio/detached.hpp // 协程分离执行标识#includeboost/asio/io_context.hpp // IO上下文事件循环#includeboost/asio/ip/tcp.hpp // TCP相关功能#includeboost/asio/signal_set.hpp // 信号处理#includeboost/asio/write.hpp // 异步写操作// 简化常用的Boost.Asio协程相关类型/函数名usingboost::asio::ip::tcp;usingboost::asio::awaitable;// 协程返回类型usingboost::asio::co_spawn;// 启动协程的函数usingboost::asio::detached;// 协程分离执行不等待完成usingboost::asio::use_awaitable;// 异步操作适配协程的等待令牌// 协程本地上下文命名空间别名用于获取当前协程的执行器namespacethis_coro boost::asio::this_coro;// 协程函数处理单个客户端的回显逻辑// 参数已连接的TCP套接字通过移动语义传递避免拷贝// 返回值awaitablevoid 表示这是一个可等待的协程任务awaitablevoidecho(tcp::socket socket){try{chardata[1024];// 数据接收缓冲区大小1024字节// 无限循环处理客户端数据直到连接断开/异常for(;;){// 异步读取客户端发送的数据协程挂起等待数据到达// co_await等待异步操作完成期间不阻塞线程// async_read_some读取任意长度的数据到缓冲区返回实际读取的字节数std::size_tn co_await socket.async_read_some(boost::asio::buffer(data), use_awaitable);// 异步将读取到的数据原样回写给客户端同样通过co_await等待写完成co_await async_write(socket, boost::asio::buffer(data, n), use_awaitable);}}catch(std::exception e){// 捕获连接断开、网络异常等错误打印异常信息std::cout 回显协程异常: e.what() std::endl;}}// 协程函数TCP服务器监听逻辑等待客户端连接awaitablevoidlistener(){// 获取当前协程绑定的执行器调度器用于后续创建接收器/套接字auto executor co_await this_coro::executor;// 创建TCP接收器绑定到指定执行器监听IPv4的10086端口tcp::acceptor acceptor(executor, { tcp::v4(), 10086 });// 无限循环等待客户端连接for(;;){// 异步等待客户端接入协程挂起有新连接时返回已连接的套接字tcp::socket socket co_await acceptor.async_accept(use_awaitable);// 启动新的协程处理该客户端的回显逻辑// detached新协程独立执行不阻塞当前监听协程// std::move转移套接字所有权到echo协程co_spawn(executor, echo(std::move(socket)), detached);}}intmain(){try{// 创建IO上下文参数1表示用1个线程运行事件循环boost::asio::io_context io_context(1);// 定义信号集监听SIGINTCtrlC和SIGTERM进程终止信号boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);// 异步等待信号触发收到信号后停止IO上下文优雅退出程序signals.async_wait([](auto, auto){io_context.stop();});// 启动监听协程detached表示协程后台运行不阻塞main函数co_spawn(io_context, listener(), detached);// 运行IO上下文的事件循环处理所有异步操作和协程任务io_context.run();}catch(std::exception e){// 捕获服务器启动阶段的异常如端口被占用打印错误信息std::cout 主程序异常: e.what() std::endl;}return0;}总结协程核心特性可暂停、可恢复、用户态调度、低开销。代码中体现awaitable标记协程函数co_await实现挂起等待依托io_context完成调度。核心价值用同步写法实现异步IO避免回调嵌套提升代码可读性和并发效率。