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协程搭建异步服务器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c++实现发送http请求通过get方式获取网页源代码

    c++实现发送http请求通过get方式获取网页源代码

    这篇文章主要介绍了c++实现发送http请求,通过get方式获取网页源代码的示例,需要的朋友可以参考下
    2014-02-02
  • C语言题目:有多少张桌子--并查集

    C语言题目:有多少张桌子--并查集

    并查集是一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组 (2) 将元素a和b合并为同一组,需要的朋友可以参考下
    2021-09-09
  • C++ OpenCV实现抖音"蓝线挑战"特效

    C++ OpenCV实现抖音"蓝线挑战"特效

    这篇文章主要介绍了如何使用OpenCV C++ 实现抖音上的特效“蓝线挑战”。文中的示例代码讲解详细,对我们学习OpenCV有一定的帮助,需要的可以参考一下
    2022-01-01
  • Windows下使用C++的方式获取Windows的硬件信息的方法小结

    Windows下使用C++的方式获取Windows的硬件信息的方法小结

    在IT领域,获取系统硬件信息是常见的需求,无论是用于设备管理、故障排查还是软件定制,本文将详细讨论如何使用C++获取Windows的硬件信息,需要的朋友可以参考下
    2025-07-07
  • getdate()函数的用法实例

    getdate()函数的用法实例

    getdate()函数的用法实例,需要的朋友可以参考一下
    2013-03-03
  • C++中4种强制类型转换的区别总结

    C++中4种强制类型转换的区别总结

    C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。下面这篇文章主要给大家介绍了C++中4种强制类型转换的区别,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • 枚举和宏的区别详细解析

    枚举和宏的区别详细解析

    枚举常量具有类型,但宏没有类型,枚举变量具有与普通变量相同的诸如作用域、值等性质,但宏没有,宏不是语言的一部分,它是一种预处理替换符
    2013-09-09
  • C++ requires关键字简单介绍

    C++ requires关键字简单介绍

    requires 是 C++20 中引入的一个新关键字,用于在函数模板或类模板中声明所需的一组语义要求,它可以用来限制模板参数,类似于 typename 和 class 关键字,这篇文章主要介绍了C++ requires关键字简介,需要的朋友可以参考下
    2023-05-05
  • C++中运算符重载的规则语法实例

    C++中运算符重载的规则语法实例

    今天小编就为大家分享一篇关于C++中运算符重载的规则语法实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 基于C语言实现http下载器

    基于C语言实现http下载器

    做OTA升级功能时,我们能直接拿到的往往只是升级包的链接,需要我们自己去下载,这时候就需要用到http下载器。本文将利用C语言实现简单的http下载器,感兴趣的可以了解一下
    2022-12-12

最新评论