上手 cpp-httplib:轻量级 C++ HTTP 库的安装与实战指南 - 教程

news/2025/10/1 17:08:13/文章来源:https://www.cnblogs.com/tlnshuju/p/19122565

上手 cpp-httplib:轻量级 C++ HTTP 库的安装与实战指南 - 教程

2025-10-01 17:04  tlnshuju  阅读(0)  评论(0)    收藏  举报

如果你在找一个 “不折腾” 的 C++ HTTP 库 —— 不用搭复杂依赖、不用啃几千行文档,还能跨平台跑 HTTP 服务和客户端,那 cpp-httplib 大概率是你的菜。作为一个单头文件的轻量级库,它把 HTTP 客户端 / 服务器的核心功能封装得简洁又好用,尤其适合快速开发小型 Web 服务、API 调用工具,或是给 C++ 项目加个 HTTP 接口。这篇文章就从安装到实战,带你一步步把 cpp-httplib 用起来。

一、先搞懂:cpp-httplib 到底好在哪?

在开始写代码前,先聊聊它的核心优势 —— 毕竟选库就像挑工具,得先知道它擅长啥:

  1. 真正的 “零依赖”:整个库就一个httplib.h头文件,不用装 Boost、不用配 curl,拷贝到项目里#include就能用,对新手太友好了。

  2. 跨平台无压力:Windows(MinGW/MSVC)、Linux、macOS 都能跑,编译命令改改参数就行,不用为不同系统写两套代码。

  3. 同步 / 异步都支持:简单场景用同步调用(比如客户端发个请求等响应),高并发场景用异步操作,不用自己手撸线程池。

  4. HTTP/1.1 特性拉满:支持持久连接、管道化,还有文件上传必备的multipart/form-data,做个简单的文件服务器也没问题。

  5. HTTPS/WSS 能搞定:虽然默认不带 SSL,但对接 OpenSSL 或 mbedTLS 后就能跑 HTTPS,编译时加个链接参数的事儿。

  6. API 设计很直观:比如服务器注册 GET 接口就用Server::Get(),客户端发 POST 请求就用Client::Post(),看函数名就知道干啥的,不用查半天文档。

二、5 分钟搞定安装:就一行克隆命令

cpp-httplib 没有复杂的 “配置 - 编译 - 安装” 流程,直接从 GitHub 拉取源码就行,步骤就两步:

1. 克隆源码到本地

打开终端(Linux/macOS)或 Git Bash(Windows),执行以下命令,把源码拉到你的工作目录(比如~/workspace):

git clone https://github.com/yhirose/cpp-httplib.git

拉完后,你会看到cpp-httplib目录下有个httplib.h—— 这就是整个库的核心,其他文件大多是示例和文档,不用管。

2. 项目中引用头文件

不用把库 “安装” 到系统目录,直接在你的 C++ 代码里指定头文件路径就行:

  • 如果你把cpp-httplib目录和你的代码文件(比如main.cc)放同级,引用方式是:
#include "cpp-httplib/httplib.h"
  • 如果你只拷贝了httplib.h到代码目录,直接引:
#include "httplib.h"

三、核心类与接口:搞懂这 4 个就够了

cpp-httplib 的核心逻辑围绕 4 个关键结构 / 类展开:Request(请求)、Response(响应)、Server(服务器)、Client(客户端)。搞懂它们的成员和方法,基本就能应对 80% 的场景。

1. Request:解析客户端发来的请求

当客户端(比如浏览器)发请求到服务器时,cpp-httplib 会把请求信息封装成httplib::Request对象,你可以从里面拿到这些关键信息:

成员作用说明示例
method请求方法(GET/POST/PUT/DELETE 等)req.method == "GET"
path请求路径(比如/hi/user/123req.path == "/hi"
headers请求头(键值对,比如User-Agentreq.headers["User-Agent"]
paramsURL 参数(比如/search?name=test里的namereq.params["name"]
body请求体(POST/PUT 请求的内容,比如表单数据)req.body

比如客户端发GET /search?keyword=cpp,你就能通过req.path拿到/search,通过req.params["keyword"]拿到cpp

2. Response:构造服务器要返回的响应

你需要通过httplib::Response对象组装响应,核心方法和成员:

  • set_content(const std::string &content, const std::string &content_type):设置响应体内容和类型。比如返回 HTML 就用text/html,返回 JSON 就用application/json

  • set_header(const std::string &key, const std::string &val):设置响应头,比如跨域需要的Access-Control-Allow-Origin: *

  • status:HTTP 状态码(200 成功、404 找不到、500 服务器错误等)。

示例:返回一个 HTML 页面,状态码 200:

rsp.set_content("

Hello from cpp-httplib

", "text/html"); rsp.status = 200;

3. Server:搭建 HTTP 服务器

httplib::Server是服务器的核心类,主要用来注册路由(比如 “访问/hi时执行什么逻辑”)和启动服务。

核心方法:注册请求处理器

服务器需要知道 “收到哪种请求、哪个路径时,执行什么代码”,这就需要用这些方法:

其中:

启动服务:listen()方法

注册完路由后,用listen(host, port)启动服务器,比如监听所有网卡(0.0.0.0)的 8080 端口:

if (_server.listen("0.0.0.0", 8080)) {std::cout << "Server running on http://0.0.0.0:8080" << std::endl;
} else {std::cerr << "Failed to start server" << std::endl;
}

4. Client:发送 HTTP 请求

如果你的 C++ 程序需要调用其他 HTTP 服务(比如调用接口获取数据),就用httplib::Client

构造 Client

先创建客户端对象,指定目标服务的主机和端口:

// 访问本地8080端口的服务
httplib::Client client("localhost", 8080);
// 访问远程服务,比如百度(注意端口80)
httplib::Client baidu_client("www.baidu.com", 80);
发送请求

客户端支持 GET/POST/PUT/DELETE 等请求,以常用的 GET 和 POST 为例:

  • GET 请求:如果需要带请求头,传Headers对象;不需要就传空。
// 发送GET /hi 请求,不带请求头
auto res = client.Get("/hi");
// 检查响应是否成功(状态码200)
if (res && res->status == 200) {std::cout << "Response: " << res->body << std::endl;
}
  • POST 请求:需要传请求体(比如 JSON 字符串)和内容类型(content_type):
// POST一个JSON数据
std::string json_body = R"({"name": "cpp-httplib", "version": "0.12.0"})";
auto res = client.Post("/api/save", json_body, "application/json");

四、实战:写一个 “Hello World” 服务器

光说不练假把式,我们基于文档里的示例,写一个完整的 HTTP 服务器 —— 访问http://localhost:8080/hi时,返回一个 HTML 页面,显示 “Hello World”。

1. 完整代码(main.cc)

#include "cpp-httplib/httplib.h"
#include 
// 封装一个HelloServer类,让代码更规整
class HelloServer {
public:// 构造函数:初始化端口,注册路由HelloServer(int port) : _port(port) {// 注册GET /hi 的处理器:调用HelloWorld方法_server.Get("/hi", std::bind(&HelloServer::HelloWorld,  // 要绑定的成员函数this,                      // 指向当前对象的指针std::placeholders::_1,     // 占位符:第一个参数(Request)std::placeholders::_2      // 占位符:第二个参数(Response)));}// 启动服务器void run() {std::cout << "Starting server on http://0.0.0.0:" << _port << "..." << std::endl;// 监听0.0.0.0(所有网卡)的_port端口if (!_server.listen("0.0.0.0", _port)) {std::cerr << "Failed to start server! Maybe port " << _port << " is used." << std::endl;}}
private:// 处理GET /hi 的逻辑void HelloWorld(const httplib::Request &req, httplib::Response &rsp) {// 1. 构造响应体:HTML内容std::string html_body = R"(cpp-httplib Test

Hello World! This is cpp-httplib Server

)";// 2. 设置响应内容和类型(text/html)rsp.set_content(html_body, "text/html");// 3. 设置HTTP状态码:200 OKrsp.status = 200;// 4. 可选:加个响应头(比如设置字符编码)rsp.set_header("Content-Type", "text/html; charset=utf-8");}int _port; // 服务器端口httplib::Server _server; // cpp-httplib服务器对象 }; int main() {// 创建服务器实例,端口8080HelloServer server(8080);// 启动服务器(会阻塞当前线程)server.run();return 0; }

2. 代码解析

  • 类封装:把服务器逻辑放到HelloServer类里,比写全局函数更规整,后续加路由(比如/about)也方便。

  • 路由绑定:用std::bind把成员函数HelloWorld绑定到/hi路由 —— 因为Handler需要的是全局函数或无捕获的 lambda,而成员函数需要this指针,所以必须用bind

  • 响应构造:不仅返回了 HTML 内容,还加了 CSS 样式和字符编码头,避免中文乱码(虽然这里没中文,但好习惯要养成)。

五、编译与运行:就一条命令

cpp-httplib 需要 C++11 及以上标准,推荐用 C++17(兼容性更好),编译时还要加-pthread(因为库内部用了线程)。

1. 编译命令

在代码目录下执行:

g++ -std=c++17 main.cc -o hello_server -pthread
  • -std=c++17:指定 C++17 标准。

  • -o hello_server:生成可执行文件名为hello_server

  • -pthread:链接线程库,必须加,否则会编译报错。

2. 运行与测试

  • 启动服务器
./hello_server

看到Starting server on ``http://0.0.0.0:8080``...就说明启动成功了。

  • 测试访问
  1. 用浏览器打开http://localhost:8080/hi,会看到居中的 “Hello World” 标题。

  2. 用 curl 命令测试(适合服务器环境):

curl http://localhost:8080/hi

会输出完整的 HTML 代码。

  • 停止服务器:按Ctrl+C即可。

六、注意事项:避坑指南

  1. 端口占用:如果启动时报 “Failed to start server”,大概率是 8080 端口被其他程序占用,换个端口(比如 8081)就行。

  2. HTTPS 支持:如果需要跑 HTTPS,编译时要链接 OpenSSL 库:

g++ -std=c++17 main.cc -o hello_server -pthread -lssl -lcrypto

然后创建SSLServer对象(而不是Server):

httplib::SSLServer ssl_server;
  1. 跨平台编译
  • Windows:用 MinGW 的 g++,命令和 Linux 一样;或用 MSVC(VS2019 及以上),在项目属性里加/std:c++17/MT(静态链接)。

  • macOS:和 Linux 完全一样,直接用系统自带的 g++ 或 clang++。

  1. 路由匹配:支持模糊匹配,比如/user/:id能匹配/user/123,通过req.params["id"]获取参数;/file/*能匹配/file/a.txt/file/doc/b.pdf,通过req.path获取完整路径。

七、总结

cpp-httplib 的优势就在于 “轻量” 和 “易用”—— 不用花半天搭环境,一个头文件 + 几行代码就能跑起 HTTP 服务,非常适合快速开发、原型验证,或是给 C++ 项目加个简单的 Web 接口。

如果你后续需要更复杂的功能(比如拦截器、会话管理),可以去看它的官方文档(有更多示例,比如文件上传、异步客户端)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/924046.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CAD安装Error 1402权限问题解决

问题描述 由于历史版本卸载不干净,在安装CAD过程中报错 1402,具体如下: Error 1402 Could not open key:UNKNOWN\Components\BCC6186334A64285641057ABAF4A6…Verify that you have sufficient access to that key,…

题解:P9868 [NOIP2023] 词典

原题传送门。 显然,如果我们想要把一个字符串字典序尽量小,我们把这个字符串中的字符从小到大排序就行了;反过来就是把字符串中的字符从大到小排序就行了。 我们可以暴力地对于每个字符串排序,然后对于每一个字符串…

304、渭城曲

304、渭城曲304、渭城曲 唐●王维 渭城朝雨浥轻尘,客舍青青柳色新。 劝君更尽一杯酒,西出阳关无故人。【现代诗意译】 清晨的渭城 下起了一场春雨 沾湿了路边的轻尘 旅店周围 青青柳条越发清新老朋友 再喝一杯饯别酒…

AtCoder Beginner Contest 425

AtCoder Beginner Contest 425 A ~ G 题解A,B H₂O题。 A 题直接模拟,记得 \(-1^x\) 的性质。 B 题构造题,每次往空格里填最小的可用数字即可。 C 这道题就相当于有一个数字圆环,每次求其中的一段区间的和。、 嗯?…

实用指南:MySQL InnoDB表压缩:性能优化全解析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

采集网站开发网站页面设计和结构的技巧

一、 开始的开始——调研、还是调研、一直在路上…… 在只有关于疫情给老年人的带来的问题大方向下&#xff0c;我去到街上随机的拉老年人进行调研。这是我第一次如此频繁的跟陌生老年人沟通。此期间&#xff0c;跟他们的沟通中我发现除了口音上的差异&#xff0c;还有更多的是…

AT_agc052_b [AGC052B] Tree Edges XOR

考虑边权转点权,让边权满足其为相邻点权的异或和,操作变成交换两个点的点权。 随便钦定一个为根,设 d i ​ 为初始时 i 的点权,f i ​ 是 i 期望得到为多少。如果存在 d,f,满足它们是相同的集合,就有解。 注意到…

pc开奖网站开发绵阳网站建设维护

1. 安装软件准备1.1. 软件准备1.zabbix-2.4.8.tar.gz zabbix-3.0.31.tar.gz下载地址&#xff1a;https://www.zabbix.com/download2.php5.4.16.tar.gz下载地址&#xff1a;https://www.php.net/downloads.php1.2. 注意事项安装过程路径、密码尽量不要出现中文、特殊字符、空格、…

详细介绍:C语言指针进阶(进阶)

详细介绍:C语言指针进阶(进阶)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco&q…

背单词 纯英文 2025年10月

2025-10-02coronation, horrific, pal, 2025-10-01quack, dais, notation, replicate, despoil,bizarre, differentiate, banister, intelligible, incest,obligatory, deviate, recourse, delineate, haversack

「Diary Solution Set」October 2025 在凉雨停歇的那天

2025.10.1 国庆节日常被作业包围。将世界最后的空白刻印在斑驳心海 而我等蜉蝣只得抒发不足日的无奈 无名歌者哼唱着积雨云为之落泪的歌在人海发现 ARC 原来有这么多优质计数。

潍坊网站建设小程序公司企业邮箱怎么登陆

转自&#xff1a;http://blog.csdn.net/warrior_zhang/article/details/41453327 机器学习的常用方法&#xff0c;主要分为有监督学习(supervised learning)和无监督学习(unsupervised learning)。 监督学习&#xff0c;就是人们常说的分类&#xff0c;通过已有的训练样本&am…

macOS Tahoe All In One

macOS Tahoe All In OnemacOS Tahoe All In One全新 Liquid Glass 设计,看着亮丽,感觉舒心,一用好熟悉。 连续互通再进化,现已连通 iPhone 上的电话 App 和实时活动功能。 直接用“聚焦”执行数百种操作,敲敲键盘…

关于一学一做的短视频网站好wordpress聚合广告平台

一个 Java 程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作面向对象中的一些概念下表列出了 面向对象 编程中的一些概念名词说明对象对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff0c;它的状态有…

风力发电机输出功率模型综述 - 详解

风力发电机输出功率模型综述 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco…

网站程序代码wordpress 软件公司模板

改变dom样式有两种做法&#xff0c;一种是通过domNode.style.xxx "",给domNode加上内置样式&#xff0c;这种方式如果需要的样式比较多&#xff0c;就只好一个个增加&#xff0c;比较麻烦&#xff0c;还有一种方式比较聪明&#xff0c;通过在css里预设好几种不同样式…

2025年小红书创作者影响力分析报告:基于10.5万条素材构建评估模型,识别高影响力内容特征,优化推荐算法与运营策略,涵盖用户分层、互动数据、地理位置分布,提供内容策略优化与创作者成长建议。

2025年小红书创作者影响力分析报告:基于10.5万条素材构建评估模型,识别高影响力内容特征,优化推荐算法与运营策略,涵盖用户分层、互动数据、地理位置分布,提供内容策略优化与创作者成长建议。pre { white-space: …

MaopaiJD Esp8266 代码

#include <ESP8266WiFi.h> // ESP8266 WiFi功能库 #include <PubSubClient.h> // MQTT客户端库 #include <EEPROM.h> // EEPROM存储库 #include <ESP8266WebServer.h> // …

英语_错题集_25-10

正确答案是 **D. from**。 **中文解答:** 这句话的意思是:“2018年冬季奥运会于2月9日至25日在韩国举行。” 这里描述的是一个**时间段**,从开始日期(2月9日)到结束日期(2月25日)。在英语中,表示“从……到………