0

0

c++如何使用Asio库进行异步网络编程 非Boost版入门【网络编程】

冰火之心

冰火之心

发布时间:2025-12-31 19:28:03

|

678人浏览过

|

来源于php中文网

原创

Standalone Asio是轻量跨平台C++网络库,支持同步/异步I/O;需配置-std=c++17和-DASIO_STANDALONE;核心为io_context事件循环、shared_from_this生命周期管理及error_code错误处理。

c++如何使用asio库进行异步网络编程 非boost版入门【网络编程】

Asio 是一个跨平台的 C++ 网络编程库,其非 Boost 版本(即 standalone Asio)以头文件为主、无依赖、轻量易集成,非常适合学习和中小型项目。它支持同步与异步 I/O,而异步模型正是高性能网络服务的核心。下面以最简实践路径带你入门。

一、获取与配置 standalone Asio

官网地址:https://www.php.cn/link/83b7b19e6be902a7bab8244f0d83481f。下载最新 release(如 asio-X.Y.Z.tar.gz),解压后只需将 include/asioinclude/boost(仅含 asio 所需的少量 boost 头文件,实际可忽略)加入编译器 include 路径即可。C++17 或更高版本推荐启用:

  • -std=c++17(支持 std::optionalstd::variant 等现代特性)
  • -DASIO_STANDALONE(显式启用 standalone 模式,禁用 Boost 依赖)
  • Windows 下还需定义 WIN32_LEAN_AND_MEAN 避免 Windows 头冲突

二、异步 TCP 服务器:从 accept 到 read

核心思想是“发起操作 → 注册回调 → 继续运行”,不阻塞线程。以下是一个监听端口、接受连接并读取一行数据的最小异步服务器示例:

#include 
#include 
#include 
#include 

using asio::ip::tcp;

struct session : std::enable_shared_from_this {
  tcp::socket socket_;
  std::array buffer_;

  explicit session(tcp::socket socket) : socket_(std::move(socket)) {}

  void start() { do_read(); }

private:
  void do_read() {
    auto self = shared_from_this();
    socket_.async_read_some(
        asio::buffer(buffer_),
        [self](const std::error_code& ec, std::size_t length) {
          if (!ec) {
            std::cout << "Received: " << std::string(self->buffer_.data(), length);
            self->do_read(); // 继续读
          }
        });
  }
};

struct server {
  asio::io_context& ioc_;
  tcp::acceptor acceptor_;

  server(asio::io_context& ioc, short port)
      : ioc_(ioc), acceptor_(ioc, tcp::endpoint(tcp::v4(), port)) {
    do_accept();
  }

private:
  void do_accept() {
    acceptor_.async_accept([this](const std::error_code& ec, tcp::socket socket) {
      if (!ec) {
        std::make_shared(std::move(socket))->start();
      }
      do_accept(); // 接受下一个连接
    });
  }
};

int main() {
  asio::io_context ioc;
  server s(ioc, 8080);
  ioc.run(); // 启动事件循环
}

注意点:

立即学习C++免费学习笔记(深入)”;

  • shared_from_this() 保证 session 对象在回调执行期间不被销毁
  • 所有异步操作(async_acceptasync_read_some)立即返回,不等待完成
  • io_context::run() 是单线程事件循环入口;多线程可用 run_work_guard + 多个线程调用 run()

三、异步 DNS 解析与客户端连接

客户端常需解析域名再连接。Asio 提供 ip::tcp::resolver 异步解析:

PHP高级开发技巧与范例
PHP高级开发技巧与范例

PHP是一种功能强大的网络程序设计语言,而且易学易用,移植性和可扩展性也都非常优秀,本书将为读者详细介绍PHP编程。 全书分为预备篇、开始篇和加速篇三大部分,共9章。预备篇主要介绍一些学习PHP语言的预备知识以及PHP运行平台的架设;开始篇则较为详细地向读者介绍PKP语言的基本语法和常用函数,以及用PHP如何对MySQL数据库进行操作;加速篇则通过对典型实例的介绍来使读者全面掌握PHP。 本书

下载
void connect_to_host(asio::io_context& ioc, const std::string& host, const std::string& port) {
  tcp::resolver resolver(ioc);
  resolver.async_resolve(
      host, port,
      [&ioc](const std::error_code& ec, tcp::resolver::results_type results) {
        if (!ec) {
          tcp::socket socket(ioc);
          asio::async_connect(socket, results,
              [&socket](const std::error_code& ec, const tcp::endpoint&) {
                if (!ec) {
                  std::cout << "Connected!\n";
                  // 后续 send / async_read...
                }
              });
        }
      });
}

关键细节:

  • 解析结果是 endpoint 列表(支持 IPv4/IPv6 双),async_connect 会自动尝试直到成功或全部失败
  • 不要在 lambda 中直接捕获 socket 值语义对象——应使用智能指针或确保生命周期,否则可能析构后访问

四、错误处理与资源管理要点

异步操作的错误统一通过 std::error_code 回调参数传递,常见错误码如:

  • asio::error::operation_aborted:对象销毁时未完成的操作被取消(正常,无需报错)
  • asio::error::eof:对端关闭连接(read 返回 0 字节
  • asio::error::connection_reset:连接被重置(如对端崩溃)

资源安全建议:

  • std::shared_ptr 管理会跨回调生命周期的对象(如 session、socket)
  • 主动关闭连接时调用 socket.close(ec),避免残留 pending 操作
  • 若需取消所有异步操作,调用 socket.cancel()io_context.stop()(后者会终止 run)

不复杂但容易忽略:异步不是“多线程”,而是“非阻塞+回调驱动”。理解 io_context 的角色、对象生命周期和错误传播机制,比写更多 handler 更重要。写几个 echo server/client 跑通,再逐步加超时、SSL、协程(Asio 支持 C++20 coroutine)就顺了。

相关专题

更多
session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

302

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

705

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

88

2025.08.19

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

184

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

263

2023.10.25

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

202

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

187

2025.11.08

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

366

2023.07.18

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 6.3万人学习

Excel 教程
Excel 教程

共162课时 | 10.1万人学习

PHP基础入门课程
PHP基础入门课程

共33课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号