C++ 使用asio协程搭建异步服务器的过程

 更新时间:2026年03月06日 09:38:38   作者:C++ 练习生  
本文给大家介绍C++ 使用asio协程搭建异步服务器的过程,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

协程核心定义

协程是用户态轻量级执行单元,能在执行中主动暂停(挂起)并保留上下文,待条件满足后恢复执行,切换开销远低于线程;在你的Boost.Asio代码中,协程通过co_await等待异步IO(如读取客户端数据),挂起时不阻塞线程,IO完成后自动恢复,让异步代码像同步代码一样易读。

实现:

#include <iostream>
// 引入Boost.Asio协程相关头文件
#include<boost/asio/co_spawn.hpp>    // 协程创建函数
#include<boost/asio/detached.hpp>    // 协程分离执行标识
#include<boost/asio/io_context.hpp>  // IO上下文(事件循环)
#include<boost/asio/ip/tcp.hpp>      // TCP相关功能
#include<boost/asio/signal_set.hpp>  // 信号处理
#include<boost/asio/write.hpp>       // 异步写操作

// 简化常用的Boost.Asio协程相关类型/函数名
using boost::asio::ip::tcp;
using boost::asio::awaitable;   // 协程返回类型
using boost::asio::co_spawn;    // 启动协程的函数
using boost::asio::detached;    // 协程分离执行(不等待完成)
using boost::asio::use_awaitable;// 异步操作适配协程的等待令牌
// 协程本地上下文命名空间别名,用于获取当前协程的执行器
namespace this_coro = boost::asio::this_coro;

// 协程函数:处理单个客户端的回显逻辑
// 参数:已连接的TCP套接字(通过移动语义传递,避免拷贝)
// 返回值:awaitable<void> 表示这是一个可等待的协程任务
awaitable<void>echo(tcp::socket socket)
{
	try {
		char data[1024];  // 数据接收缓冲区,大小1024字节
		// 无限循环处理客户端数据,直到连接断开/异常
		for (;;)
		{
			// 异步读取客户端发送的数据,协程挂起等待数据到达
			// co_await:等待异步操作完成,期间不阻塞线程
			// async_read_some:读取任意长度的数据到缓冲区,返回实际读取的字节数
			std:: size_t n = 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服务器监听逻辑,等待客户端连接
awaitable<void>listener()
{
	// 获取当前协程绑定的执行器(调度器),用于后续创建接收器/套接字
	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);
	}
}

int main()
{
	try {
		// 创建IO上下文,参数1表示用1个线程运行事件循环
		boost::asio::io_context io_context(1);
		// 定义信号集,监听SIGINT(Ctrl+C)和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;
	}
	return 0;
}

总结

  1. 协程核心特性:可暂停、可恢复、用户态调度、低开销
  2. 代码中体现:awaitable标记协程函数,co_await实现挂起等待,依托io_context完成调度。
  3. 核心价值:用同步写法实现异步IO,避免回调嵌套,提升代码可读性和并发效率。

到此这篇关于C++ 使用asio协程搭建异步服务器的过程的文章就介绍到这了,更多相关C++ asio协程搭建异步服务器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • VSCode远程代码开发及DNS隧道端口转发实现远程办公代码

    VSCode远程代码开发及DNS隧道端口转发实现远程办公代码

    这篇文章主要介绍了VSCode远程代码开发及DNS隧道端口转发实现远程办公,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • C++实现学生成绩管理系统

    C++实现学生成绩管理系统

    这篇文章主要为大家详细介绍了C++实现学生成绩管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C++编程中new运算符的使用学习教程

    C++编程中new运算符的使用学习教程

    这篇文章主要介绍了C++编程中new运算符的使用学习教程,是C++入门学习中的基础知识,需要的朋友可以参考下
    2016-01-01
  • C++11 并发指南之std::thread 详解

    C++11 并发指南之std::thread 详解

    这篇文章主要介绍了C++11 并发指南之std::thread 详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 详解C语言解决经典问题之兔子产子

    详解C语言解决经典问题之兔子产子

    有一对兔子,从出生后的第 3 个月起每个月都生一对兔子。小兔子长到第 3 个月后每个月又生一对兔子,假设所有的兔子都不死,问 30 个月内每个月的兔子总数为多少?本文将用C语言解决这一经典问题,需要的可以参考一下
    2022-03-03
  • C语言版飞机大战游戏

    C语言版飞机大战游戏

    这篇文章主要为大家详细介绍了C语言版飞机大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • 基于C语言扫雷游戏的设计与实现

    基于C语言扫雷游戏的设计与实现

    大家好,本篇文章主要讲的是基于C语言扫雷游戏的设计与实现,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • C语言八皇后问题解决方法示例【暴力法与回溯法】

    C语言八皇后问题解决方法示例【暴力法与回溯法】

    这篇文章主要介绍了C语言八皇后问题解决方法,简单描述了八皇后问题并结合实例形式分析了C语言基于暴力法与回溯法解决八皇后的具体操作技巧,需要的朋友可以参考下
    2018-01-01
  • C/C++线程退出的四种方法小结

    C/C++线程退出的四种方法小结

    本文主要介绍了C/C++线程退出的四种方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • C++中使用cout以hex格式输出方式

    C++中使用cout以hex格式输出方式

    这篇文章主要介绍了C++中使用cout以hex格式输出方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11

最新评论