首页 关于我们 成功案例 网络营销 电商设计 新闻中心 联系方式
QQ联系
电话联系
手机联系
QQ联系
电话联系
手机联系

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

发布时间:2025-12-31 00:00
发布者:冰火之心
浏览次数:
Standalone Asio是轻量跨平台C++网络库,支持同步/异步I/O;需配置-std=c++17和-DASIO_STANDALONE;核心为io_context事件循环、shared_from_this生命周期管理及error_code错误处理。

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

一、获取与配置 standalone Asio

官网地址:https://www./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(); // 启动事件循环
}

注意点:

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

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

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

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)就顺了。


# windows  # ipv6  # 字节  # 端口  # ssl  # session  #   # ai  # c++  # ios  # 解压  # win  # dns  # echo  # EOF  # include 


相关文章: LINUX如何删除用户和用户组_Linux userdel和groupdel命令用法【系统管理】  安克发布新款氮化镓充电宝:体积缩小 30%,支持 200W 输出  如何理解Javascript的AST抽象语法树_怎样用Javascript操作AST?  如何实现javascript表单验证_正则表达式有哪些实用技巧  PHP怎么接收前端传的布尔值_处理truefalse参数转换方法指南【解答】  Django ORM 中安全处理并发更新的最佳实践  Win11输入法选字框不见了怎么办_Win11输入法修复与重置【教程】  最强祖师龙傲天四阶法宝锻造及本命养成  Win11任务栏卡死怎么办 Windows11任务栏无反应解决方法【教程】  Laravel Valet 安装失败:解决 Symfony 依赖版本冲突问题  如何使用Golang测试私有函数_Golang reflect与测试封装示例  宙斯浏览器解决网页加载慢方法 优化网络连接与预加载设置  LinuxWeb服务日志分析教程_ApacheNginx日志可视化实践  VSCode快捷键大全:从入门到精通的键盘侠养成之路  Java环境搭建后如何配置默认编码UTF8_Java编码规范说明  VSCode与GitHub Gist的集成:分享你的代码片段  小高和刚:100个结局太少!想做个《两百日战纪》  曝vivo X300 Ultra将取消拍照按键 搭载LYTIA901 2亿主摄  3步教你用AI总结会议录音,再也不怕错过重点  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  ChatGPT官方网页端入口 ChatGPT官网快速登录方法  如何解决“addFirst(int) 方法未定义”编译错误  java内置函数式接口有哪些?  以安全与健康定义好产品,小熊全玻璃养生壶荣获好产品奖  Linux多用户管理项目教程_权限策略与组策略应用  智行ai抢票怎样设置抢票通道_智行ai抢票通道选择与速度优化【指南】  css flex 容器内元素无法撑满高度怎么办_使用 stretch 并设置高度  如何使用Golang处理数据库操作错误_GolangSQL查询异常处理实践  能源行业“鸿蒙化”进入规模共创期,大批能源领域应用完成适配  整理分享:AO3可访问地址大全 实时更新的镜像入口 


相关栏目: 【 行业资讯17850 】 【 软件资源51899 】 【 网站技术89748 】 【 百度推广44206 】 【 网络营销84187 】 【 运营推广93002 】 【 AI优化91086 】 【 网络优化117696 】 【 网址导航107142