C++实现带有超时重试机制的HTTP异步请求 _ Boost.Asio实战应用【源码】

阿墨同学_9982

阿墨同学_9982

2026-05-09

1012人浏览

原创

Boost.Asio 本身不提供 HTTP 协议解析,必须手动拼接请求头、解析响应;超时和重试需为每个异步操作(resolve/connect/write/read)单独配置 deadline_timer,超时调用 socket.cancel() 并检查 operation_aborted 错误,重试仅针对 5xx、429、503 等服务端错误,且每次重试须重建 socket 和 timer 对象。

c++实现带有超时重试机制的http异步请求 _ boost.asio实战应用【源码】

如何用 Boost.Asio 发起带超时和重试的异步 HTTP 请求

直接说结论:Boost.Asio 本身不提供 HTTP 协议解析,必须自己拼接请求头、解析响应;超时和重试得靠 deadline_timer 或 C++11 steady_clock + async_wait 手动控制,不能依赖 socket::set_option(socket_base::keep_alive) —— 那只是 TCP 层保活,对 HTTP 超时不生效。

为什么 async_connect + async_write + async_read_until 容易卡死

常见错误是把整个 HTTP 流程串成“一步 async_read_until(\n\n)”就完事,结果服务器只返回部分响应、或分块传输(chunked)没处理、或中间网络抖动导致 async_read 永远等不到 \n\n。这时既没超时,也没重试触发点。

  • 必须为每个异步操作(connect / write / read header / read body)单独配一个 deadline_timer,超时后调用 socket.cancel() 并检查 error == boost::asio::error::operation_aborted
  • async_read_until 对 \n\n 不可靠:HTTP 响应头末尾是 \r\n\r\n,不是 \n\n;且某些代理会改写换行符
  • 推荐用 async_read 循环读取,手动查找 \r\n\r\n 边界,避免缓冲区溢出或死等

重试逻辑该放在哪一层:连接失败?读超时?还是状态码非 2xx?

重试不是越靠后越好。例如 503 Service Unavailable 可重试,但 404 或 401 就不该无脑重试;而 DNS 解析失败(resolve 阶段 error)或 connect 被拒绝(connection refused),通常值得立即重试 1–2 次。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 在 resolver.async_resolve 失败时,若 error 是 boost::asio::error::host_not_found,可延迟 100ms 后重 resolve
  • async_connect 超时或失败,建议指数退避:第 1 次等 200ms,第 2 次等 400ms,最多 3 次
  • 收到完整响应后,先检查 status_code:仅对 5xx 和部分 429/503 做重试;不要对 400、401、403、404 等客户端错误重试
  • 每次重试前必须销毁旧 socket 和 timer,新建对象,否则资源残留会导致未定义行为

一个最小可行的异步请求结构体怎么组织

别写成大单例或全局 handler。每个请求应封装为独立对象(如 http_request),持有自己的 tcp::socket、deadline_timer、buffer 和重试计数器。生命周期由 shared_ptr 管理,避免 handler 被销毁后回调还访问野指针。

struct http_request {
  tcp::socket sock_;
  deadline_timer timer_;
  std::string host_, port_, path_;
  int retry_count_ = 0;
  static const int MAX_RETRY = 3;

  void start() {
    resolver_.async_resolve(host_, port_,
      [self = shared_from_this()](error_code ec, results_type res) {
        if (ec) { self->on_resolve_fail(ec); return; }
        self->start_connect(res);
      });
  }

  void start_connect(results_type res) {
    timer_.expires_from_now(boost::posix_time::milliseconds(5000));
    timer_.async_wait([self = shared_from_this()](error_code ec) {
      if (!ec) self->sock_.cancel(); // 触发 connect 的 operation_aborted
    });
    boost::asio::async_connect(sock_, res,
      [self = shared_from_this()](error_code ec, endpoint_type) {
        if (ec == boost::asio::error::operation_aborted) {
          if (++self->retry_count_ start();
          return;
        }
        if (!ec) self->send_request();
      });
  }
  // … 后续 send_request / read_header / read_body 类似
};

注意 self = shared_from_this() 必须在捕获列表里显式写出,否则 lambda 持有的 this 可能悬空;timer_.async_wait 和 sock_.cancel() 配合是唯一可靠的超时中断手段。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2268

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习