赣州市网站建设_网站建设公司_色彩搭配_seo优化
2025/12/27 12:20:02 网站建设 项目流程

实用指南:Asio2: 一个基于 Boost.Asio 封装的高性能网络编程库

2025-12-27 12:17  tlnshuju  阅读(0)  评论(0)    收藏  举报

目录

1.简介

2.安装方式(适配 CMake/VCPKG)

3.核心 API 与使用示例

4.HTTP 服务器超详细示例

4.1.服务器架构设计

4.2.完整源代码(分文件组织)

4.3.CMakeLists.txt(完整构建配置)

4.4.编译运行

4.5.功能测试

4.6.启用 HTTPS 服务

5.网络教程

6.与原生 Boost.Asio 的核心差异


1.简介

        Asio2 并非 Boost 官方提供的库,而是一个基于 Boost.Asio 封装的第三方高性能网络编程库,主打简化接口、增强功能、提升开发效率,同时保持跨平台(Windows/Linux/macOS)特性,适配 C++11 及以上标准,非常适合快速开发 TCP/UDP/HTTP/SSL 等网络应用。

  • 基于原生 Boost.Asio,兼容 Boost 1.66+ 版本,同时支持 standalone Asio(不依赖完整 Boost 库)。
  • 封装了原生 Asio 繁琐的异步回调、缓冲区管理、连接管理等逻辑,提供更简洁的 API。
  • 内置断线重连、超时机制、心跳检测、SSL/TLS 加密、HTTP 协议支持,还支持 UDP 组播 / 广播、串口通信等。
  • 支持TCP,UDP,HTTP,WEBSOCKET,RPC,ICMP,SERIAL_PORT等。
  • 支持可靠UDP(基于KCP),支持SSL,支持从内存字符串加载SSL证书。
  • TCP支持数据拆包功能(按指定的分隔符对数据自动进行拆包,保证用户收到的数据是一个完整的数据包);实现了TCP的数据报模式(类似WEBSOCKET)。
  • 支持windows,linux,32位,64位。
  • 依赖asio(boost::asio或独立asio均可,若需要HTTP功能必须使用boost::asio),依赖C++17。
  • 代码采用hpp头文件方式,以源码级链入,无需编译,只需在工程的Include包含目录中添加asio2路径,然后在源码中#include <asio2/asio2.hpp>包含头文件即可。

2.安装方式(适配 CMake/VCPKG)

vcpkg: 一款免费开源的C++包管理器

1.下载地址

https://github.com/zhllxt/asio2.git

https://gitee.com/zhllxt/asio2

2.VCPKG 安装(推荐,符合你的项目构建习惯)

根据平台执行对应命令,自动下载编译并安装:

# Windows 安装 x64 版本
.\vcpkg install asio2:x64-windows
# Linux 安装 x64 版本
./vcpkg install asio2:x64-linux
# 如需支持 SSL(如 HTTPS/SSL-TCP),安装带 SSL 的版本
.\vcpkg install asio2[ssl]:x64-windows  # Windows
./vcpkg install asio2[ssl]:x64-linux    # Linux

3.CMake 配置与编译

安装后,在你的 CMakeLists.txt 中直接引用即可,VCPKG 会自动处理依赖路径:

cmake_minimum_required(VERSION 3.15)
project(asio2_demo)
# 找到 asio2 库
find_package(asio2 REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
# 链接 asio2 及依赖库
target_link_libraries(${PROJECT_NAME} PRIVATE asio2::asio2)
# 指定 C++ 标准
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)

3.核心 API 与使用示例

Asio2 的接口设计简洁,以 TCP 通信为例,核心场景的示例代码如下:

1.TCP 服务器

#include 
int main() {asio2::tcp_server server;// 连接建立回调server.bind_connect([](auto &session) {std::cout << "client connected: " << session.remote_address() << std::endl;});// 接收数据回调server.bind_recv([](auto &session, std::string_view data) {std::cout << "recv: " << data << std::endl;session.send(data); // 回声});// 启动服务器,监听 8080 端口server.start("0.0.0.0", 8080);asio2::executor::run(); // 运行事件循环return 0;
}

2.TCP 客户端(带断线重连)

#include 
int main() {asio2::tcp_client client;// 启用断线重连client.enable_reconnect(true, 3000); // 每 3 秒重连一次// 连接成功后发送数据client.bind_connect([&](auto &session) {session.send("hello server");});// 启动客户端,连接服务器client.start("127.0.0.1", 8080);asio2::executor::run();return 0;
}

4.HTTP 服务器超详细示例

4.1.服务器架构设计

采用模块化拆分,避免回调地狱,核心模块如下:

  1. 路由管理器:统一管理 GET/POST 路由,支持路径匹配
  2. 请求处理器:解析 GET 参数、POST 表单 / JSON 数据
  3. 静态文件管理器:处理静态资源请求,支持文件类型映射
  4. 响应构造器:统一封装 HTTP 响应(状态码、响应头、响应体)
  5. 错误处理器:捕获并返回 400/403/404/500 等标准错误

4.2.完整源代码(分文件组织)

头文件 http_server.h(模块声明)

#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
// 命名空间别名,简化代码
using json = nlohmann::json;
using TcpSession = asio2::tcp_session;
using HttpRequest = asio2::http_request;
using HttpResponse = asio2::http_response;
using RouteHandler = std::function;
// 1. 路由管理器类:管理 GET/POST 路由映射
class RouteManager {
public:// 注册 GET 路由void get(const std::string& path, RouteHandler handler);// 注册 POST 路由void post(const std::string& path, RouteHandler handler);// 匹配路由并执行处理函数bool match(const std::string& method, const std::string& path, const HttpRequest& req, HttpResponse& resp);
private:std::unordered_map get_routes_;  // GET 路由表std::unordered_map post_routes_; // POST 路由表
};
// 2. 静态文件管理器类:处理静态资源请求
class StaticFileManager {
public:// 设置静态文件根目录void set_root(const std::string& root);// 处理静态文件请求bool handle(const std::string& path, HttpResponse& resp);
private:// 根据文件后缀获取 Content-Typestd::string get_content_type(const std::string& filename);std::string root_dir_ = "./static/"; // 默认静态文件目录
};
// 3. HTTP 服务器核心类
class HttpServer {
public:HttpServer();// 启动服务器bool start(const std::string& ip, uint16_t port);// 获取路由管理器(用于注册路由)RouteManager& router();
private:// 核心请求处理回调void on_recv(TcpSession& session, std::string_view data);// 错误处理void on_error(TcpSession& session, const boost::system::error_code& ec);// 404 处理void handle_404(HttpResponse& resp);// 500 处理void handle_500(HttpResponse& resp);
private:asio2::tcp_server server_;RouteManager router_;StaticFileManager static_manager_;
};

源文件 http_server.cpp(模块实现)

#include "http_server.h"
#include 
#include 
namespace fs = std::filesystem;
// -------------------------- RouteManager 实现 --------------------------
void RouteManager::get(const std::string& path, RouteHandler handler) {get_routes_[path] = std::move(handler);
}
void RouteManager::post(const std::string& path, RouteHandler handler) {post_routes_[path] = std::move(handler);
}
bool RouteManager::match(const std::string& method, const std::string& path, const HttpRequest& req, HttpResponse& resp) {if (method == "GET" && get_routes_.count(path)) {get_routes_[path](req, resp);return true;}if (method == "POST" && post_routes_.count(path)) {post_routes_[path](req, resp);return true;}return false;
}
// -------------------------- StaticFileManager 实现 --------------------------
void StaticFileManager::set_root(const std::string& root) {root_dir_ = root;// 确保目录以路径分隔符结尾if (!root_dir_.empty() && root_dir_.back() != fs::path::preferred_separator) {root_dir_ += fs::path::preferred_separator;}
}
std::string StaticFileManager::get_content_type(const std::string& filename) {std::unordered_map mime_map = {{".html", "text/html; charset=utf-8"},{".css", "text/css; charset=utf-8"},{".js", "application/javascript; charset=utf-8"},{".txt", "text/plain; charset=utf-8"},{".jpg", "image/jpeg"},{".png", "image/png"},{".json", "application/json; charset=utf-8"}};std::string ext = fs::path(filename).extension().string();return mime_map.count(ext) ? mime_map[ext] : "application/octet-stream";
}
bool StaticFileManager::handle(const std::string& path, HttpResponse& resp) {// 拼接真实文件路径,防止路径穿越攻击fs::path real_path = fs::canonical(root_dir_ + path.substr(8)); // 截取 /static/ 后的路径// 路径校验:必须在静态目录内if (!fs::exists(real_path) || !fs::is_regular_file(real_path)) {return false;}// 设置响应头和文件内容resp.status(200, "OK");resp.set_header("Content-Type", get_content_type(real_path.filename().string()));// asio2 的 send_file 支持大文件断点续传resp.body(asio2::send_file(real_path.string()));return true;
}
// -------------------------- HttpServer 实现 --------------------------
HttpServer::HttpServer() {// 绑定数据接收回调和错误回调server_.bind_recv(std::bind(&HttpServer::on_recv, this, std::placeholders::_1, std::placeholders::_2));server_.bind_error(std::bind(&HttpServer::on_error, this, std::placeholders::_1, std::placeholders::_2));
}
bool HttpServer::start(const std::string& ip, uint16_t port) {try {server_.start(ip, port);std::cout << "HTTP Server started on http://" << ip << ":" << port << std::endl;asio2::executor::run();return true;} catch (const std::exception& e) {std::cerr << "Server start failed: " << e.what() << std::endl;return false;}
}
RouteManager& HttpServer::router() {return router_;
}
void HttpServer::on_recv(TcpSession& session, std::string_view data) {try {HttpRequest req(data);HttpResponse resp;// 设置通用响应头resp.set_header("Access-Control-Allow-Origin", "*");resp.set_header("Server", "Asio2-Modular-HTTP-Server");std::string method = req.method();std::string path = req.path();// 1. 优先匹配路由if (router_.match(method, path, req, resp)) {session.send(resp.buffer());return;}// 2. 匹配静态文件请求(路径以 /static/ 开头)if (path.starts_with("/static/") && static_manager_.handle(path, resp)) {session.send(resp.buffer());return;}// 3. 路由未匹配,返回 404handle_404(resp);session.send(resp.buffer());} catch (const std::exception& e) {// 捕获异常,返回 500HttpResponse resp;handle_500(resp);session.send(resp.buffer());std::cerr << "Request handle error: " << e.what() << std::endl;}
}
void HttpServer::on_error(TcpSession& session, const boost::system::error_code& ec) {if (ec) {std::cerr << "Session error: " << ec.message() << " (client: " << session.remote_address() << ")" << std::endl;}
}
void HttpServer::handle_404(HttpResponse& resp) {resp.status(404, "Not Found");resp.content_type("text/html; charset=utf-8");resp.body("

404 Not Found

请求的资源不存在

"); } void HttpServer::handle_500(HttpResponse& resp) {resp.status(500, "Internal Server Error");resp.content_type("text/html; charset=utf-8");resp.body("

500 Internal Server Error

服务器内部错误

"); }

主函数 main.cpp(服务器启动与路由注册)

#include "http_server.h"
int main() {// 1. 创建 HTTP 服务器实例HttpServer server;// 2. 获取路由管理器,注册路由RouteManager& router = server.router();// 3. 注册 GET 路由// 3.1 根路径:欢迎页面router.get("/", [](const HttpRequest& req, HttpResponse& resp) {resp.status(200, "OK");resp.content_type("text/html; charset=utf-8");resp.body(R"(

Boost.Asio2 模块化 HTTP 服务器

支持 GET/POST/静态文件/JSON 响应

  • /hello/Asio2
  • /api/json
  • /static/test.txt
)");});// 3.2 动态参数路由:/hello/xxxrouter.get("/hello/:name", [](const HttpRequest& req, HttpResponse& resp) {std::string name = req.path().substr(7); // 截取 /hello/ 后的参数resp.status(200, "OK");resp.content_type("text/plain; charset=utf-8");resp.body("Hello, " + name + "!");});// 3.3 JSON 接口router.get("/api/json", [](const HttpRequest& req, HttpResponse& resp) {resp.status(200, "OK");resp.content_type("application/json; charset=utf-8");json data = {{"code", 200},{"message", "success"},{"data", {{"server_name", "Asio2-HTTP-Server"},{"version", "2.0.0"},{"method", req.method()}}}};resp.body(data.dump(2)); // 格式化 JSON 输出});// 4. 注册 POST 路由// 4.1 解析 JSON 格式的 POST 请求router.post("/api/login", [](const HttpRequest& req, HttpResponse& resp) {// 从请求体解析 JSON 数据json req_body = json::parse(req.body());std::string username = req_body.value("username", "");std::string password = req_body.value("password", "");// 模拟登录校验json res_data;if (username == "admin" && password == "123456") {res_data = {{"code", 200}, {"message", "登录成功"}};} else {res_data = {{"code", 401}, {"message", "用户名或密码错误"}};}resp.status(200, "OK");resp.content_type("application/json; charset=utf-8");resp.body(res_data.dump());});// 4.2 解析表单格式的 POST 请求router.post("/api/form", [](const HttpRequest& req, HttpResponse& resp) {// asio2 内置解析表单数据(x-www-form-urlencoded)std::string name = req.form_value("name");std::string age = req.form_value("age");resp.status(200, "OK");resp.content_type("text/plain; charset=utf-8");resp.body("Name: " + name + ", Age: " + age);});// 5. 启动服务器,监听 8080 端口server.start("0.0.0.0", 8080);return 0; }

4.3.CMakeLists.txt(完整构建配置)

适配 VCPKG,支持条件编译 HTTPS,可直接复用:

cmake_minimum_required(VERSION 3.15)
project(asio2_http_server_modular)
# 配置 C++ 标准
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# 查找依赖库
find_package(asio2 REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(OpenSSL REQUIRED) # HTTPS 依赖
# 创建可执行文件
add_executable(${PROJECT_NAME}main.cpphttp_server.cpphttp_server.h
)
# 链接依赖库
target_link_libraries(${PROJECT_NAME} PRIVATEasio2::asio2nlohmann_json::nlohmann_jsonOpenSSL::SSLOpenSSL::Crypto
)
# 跨平台编译配置
if (WIN32)# Windows 平台额外链接 ws2_32 库target_link_libraries(${PROJECT_NAME} PRIVATE ws2_32)
elseif (UNIX)# Linux 平台额外链接 pthread 库target_link_libraries(${PROJECT_NAME} PRIVATE pthread)
endif ()

4.4.编译运行

# 创建 build 目录
mkdir build && cd build
# Windows (Visual Studio 2022)
cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE="D:/vcpkg/scripts/buildsystems/vcpkg.cmake"
cmake --build . --config Release
# Linux (GCC)
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="$HOME/vcpkg/scripts/buildsystems/vcpkg.cmake"
make -j4
# 运行服务器
./Release/asio2_http_server_modular.exe # Windows
./asio2_http_server_modular # Linux

4.5.功能测试

1.GET 请求测试

# 根路径
curl http://127.0.0.1:8080
# 动态参数路由
curl http://127.0.0.1:8080/hello/Asio2
# JSON 接口
curl http://127.0.0.1:8080/api/json
# 静态文件
curl http://127.0.0.1:8080/static/test.txt

2.POST 请求测试

# JSON 格式 POST(登录接口)
curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"123456"}' http://127.0.0.1:8080/api/login
# 表单格式 POST
curl -X POST -d "name=test&age=20" http://127.0.0.1:8080/api/form

3.错误场景测试

  • 访问不存在的路径:http://127.0.0.1:8080/404(返回 404)
  • 访问静态目录外的文件:http://127.0.0.1:8080/static/../main.cpp(返回 404,路径穿越防护生效)

4.6.启用 HTTPS 服务

修改 HttpServer::start 方法,添加 SSL 配置(需准备证书文件 server.crt 和密钥 server.key):

bool HttpServer::start(const std::string& ip, uint16_t port) {try {// SSL 配置server_.use_ssl("server.crt", "server.key");server_.start(ip, port);std::cout << "HTTPS Server started on https://" << ip << ":" << port << std::endl;asio2::executor::run();return true;} catch (const std::exception& e) {std::cerr << "Server start failed: " << e.what() << std::endl;return false;}
}

5.网络教程

基于c++和asio的网络编程框架asio2教程基础篇:1、基本概念和使用说明

开源基于asio的网络通信框架asio2,支持TCP,UDP,HTTP,WEBSOCKET,RPC,ICMP,SSL,串口,跨平台,支持可靠UDP,支持TCP自动拆包等

使用asio2开发一个简易的http server

asio做tcp的自动拆包时,asio的match condition如何使用的详细说明

基于c++和asio的网络编程框架asio2教程基础篇:4、使用tcp客户端发送数据时,如何同步获取服务端返回结果

基于c++和asio的网络编程框架asio2教程使用篇:使用rpc模块编写rpc server和rpc client

rpc性能测试

关于asio2项目example目录中的几个tcp示例的说明

基于c++和asio的网络编程框架asio2教程基础篇:3、各个回调函数的触发线程以及多线程总结

基于c++和asio的网络编程框架asio2教程基础篇:2、各个回调函数的触发顺序和执行流程

6.与原生 Boost.Asio 的核心差异

  • 接口复杂度:Asio2 封装了 io_contextstrand 等底层对象,无需手动管理异步操作的线程安全。
  • 功能集成:原生 Asio 需手动实现断线重连、心跳等功能,Asio2 已内置成熟方案。
  • 兼容性:Asio2 可无缝调用原生 Asio 的接口,方便项目逐步迁移。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询