【Linux】【网络】工具:httplib 库的安装与简单使用

news2024/12/23 7:06:36

文章目录

      • 1. 下载 httplib 库
      • 2. 从 Win 传输文件到 Linux
      • 3. 解压缩
  • httplib 库
    • 1. struct Request 结构体源码展示
    • 2. struct Reponse 结构体源码展示
    • 3. httplib 库 Server 类
    • 4. httplib 库 Client 类
    • 5. 搭建简易 server 服务器
    • 6. 搭建简易 client 客户端

1. 下载 httplib 库

  • 要求联网,笔者使用云服务器,在 Xshell 7 上完成的虚拟机操作。

  • 安装 git 工具,通过代码 clone
    (大概率连接不上,推荐直接浏览器下载)

sudo yum install -y git
git clone https://github.com/yhirose/cpp-httplib.git
  • 浏览器访问链接下载压缩包

🔗Github 链接

在这里插入图片描述


2. 从 Win 传输文件到 Linux

  • 下载文件传输工具
sudo yum install -y lrzsz
  • 笔者使用 Xshell7,可以将下载好的两个压缩包直接拖拽到 Xshell 界面后接收。也可以手下下面代码,在弹窗中选择两个压缩包文件进行传输。
rz -E

3. 解压缩

  • 安装解压缩工具
sudo yum install -y unzip
  • 对文件解压缩
unzip cpp-httplib-master.zip

httplib 库


httplib 库,一个 C++11 单文件头的跨平台 HTTP/HTTPS 库。安装起来非常容易。只需包含 httplib.h 在代码中即可。

httplib 库实际上是用于搭建一个简单的 http 服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率。


1. struct Request 结构体源码展示

Request 结构体的作用:

  1. 客户端保存的所有 http 请求相关信息,最终组织 http 请求发送给服务器
  2. 服务器收到 http 请求之后进行解析,将解析的数据保存在 Request 结构体中, 待后续处理

Request 源代码(部分):

struct Request {
	std::string method;			// 请求方法
	std::string path;			// 资源路径
	Headers headers;			// 头部字段
	std::string body;			// 正文
	// for server
	std::string version;		// 协议版本
	Params params;				// 查询字符串
	MultipartFormDataMap files;	// 保存的是客户端上传的文件,里面有四个字段,详细代码见后文
	Ranges ranges;				// 用于实现断点续传的请求文件区间

	
	// API
	bool has_header(const std::string &key) const;								// 查询 headers 里面有没有某个字段
	std::string get_header_value(const std::string &key, size_t id = 0) const;	// 获取头部字段
	void set_header(const std::string &key, const std::string &val);			// 设置头部字段的值
	bool has_file(const std::string &key) const;								// 是否包含某个文件,从 files 字段中获得的
	MultipartFormData get_file_value(const std::string &key) const;				// 获取文件信息

};
struct MultipartFormData {
	std::string name;			// 字段名称
	std::string content;		// 字段内容
	std::string filename;		// 文件名称
	std::string content_type;	// 正文类型
};

2. struct Reponse 结构体源码展示

Reponse 结构体的作用:

  1. 用户将响应数据放到结构体中,httplib 会将其中的数据按照 http 响应格式组织成为 http 响应,发送给客户端。

Request 源代码(部分):

struct Response {
	std::string version;	// 协议版本
	int status = -1;		// 响应版本
	Headers headers;		// 头部字段
	std::string body;		// 响应给客户端的正文
	
	// API
	void set_header(const std::string &key, const std::string &val);			// 设置头部字段,放入 headers
	void set_content(const std::string &s, const std::string &content_type);	// 设置正文,放入 body
};

3. httplib 库 Server 类

httplib 库的 Server 类,就是用来快速搭建 http 服务器的。

class Server {
	using Handler = std::function<void(const Request &, Response &)>;	// 处理请求任务回调函数
	using Handlers = std::vector<std::pair<std::regex, Handler>>;		// 请求与处理函数映射表
	std::function<TaskQueue *(void)> new_task_queue;		// 线程池,处理 http 请求
	// 针对某种请求方法的某个请求设定映射的处理函数
	Server &Get(const std::string &pattern, Handler handler);
	Server &Post(const std::string &pattern, Handler handler);
	Server &Put(const std::string &pattern, Handler handler);
	Server &Patch(const std::string &pattern, Handler handler);  
	Server &Delete(const std::string &pattern, Handler handler);
	Server &Options(const std::string &pattern, Handler handler);
	// 搭建并启动 http 服务器
	bool listen(const char *host, int port, int socket_flags = 0);
};
  1. Handler:函数指针类型,定义了一个 http 请求任务处理 回调函数 的格式。
using Handler = std::function<void(const Request &, Response &)>;
  • 参数 Request:保存请求数据,让用户能够根据请求数据进行业务处理。
  • 参数 Response:需要用户在业务处理中,填充数据,最终要响应给客户端。

httplib 搭建的服务器收到请求后,进行解析,得到一个 Request 结构体,其中根据请求数据 server 去处理这个请求,这个函数定义的格式就是 Handler 格式。

  1. Handlers:请求路由数组,其中包含了两个信息,
using Handlers = std::vector<std::pair<std::regex, Handler>>;
  • 参数 regex:正则表达式,用于匹配 http 请求资源路径
  • 参数 Handler:请求处理函数指针

可以理解作,Handlers是一 张表, 将一个客户端请求的资源路径 和一个处理函数(用户自己定义的函数) 建立映射关系。

当服务器收到请求解析得到 Request 就会根据资源路径以及请求方法到这张表中查看有没有对应的处理函数。如果有则调用这个函数进行请求处理,如果没有则响应 404。

简单说来,handlers 这个表就决定了,哪个请求应该用哪个函数处理。

  1. new_ task_ queue :线程池,处理 http 请求。httplib 收到一个新建连接,则将新的客户端连接抛入线程池中。
std::function<TaskQueue *(void)> new_task_queue;

线程池中线程的工作 :

  • 接收请求,解析请求,得到 Request 结构体也就是请求的数据
  • 在 Handlers 映射表中,根据请求信息查找处理函数,如果有则调用函数处理 void(const Request &, Response &)
  • 当处理函数调用完毕,根据函数返回的 Response 结构体中的数据组织 http 响应发送给客户端

4. httplib 库 Client 类

httplib 库的 Client 类,是用来快速搭建 http 客户端的。

class Client {
	Client(const std::string &host, int port);		// 传入服务器 IP 和 端口
	// 向客户端发送的各种请求
	Result Get(const char *path, const Headers &headers);
	Result Post(const char *path, const char *body, size_t content_length,const char *content_type);
	Result Post(const char *path, const MultipartFormDataItems &items);	// Post 请求提交多区域数据,常用于多文件上传,类型源码见上文
};

5. 搭建简易 server 服务器

搭建 server.cpp 代码如下:

#include "httplib.h"

void Hello(const httplib::Request &req, httplib::Response &rsp)
{
    rsp.set_content("hello world!", "text/plain");
    rsp.status = 200;
}

void Numbers(const httplib::Request &req, httplib::Response &rsp)
{
    auto num = req.matches[1]; // [0]里面保存的是整体 path,往后的下标中保存捕捉的数据即,.matches[]中
    rsp.set_content(num, "text/plain");
    rsp.status = 200;
}

void Multipart(const httplib::Request &req, httplib::Response &rsp)
{
    auto ret = req.has_file("filexxx");
    if (ret == false)
    {
        std::cout << "not file upload\n";
        rsp.status = 404;
    }
    const auto& file = req.get_file_value("filexxx");  // 获取文件区域数据信息
    rsp.body.clear();
    rsp.body = file.filename;   // 文件名称
    rsp.body += "\n";
    rsp.body += file.content;   // 文件内容
    rsp.set_header("Content-Type", "text/plain");
    rsp.status = 200;
}

int main()
{
    httplib::Server server; // 实例化一个 server 类的对象用于搭建服务器

    server.Get("/hi", Hello); // 注册一个针对 /hi 的 Get 请求的处理函数映射关系
    server.Get("/numbers/(\\d+)", Numbers);
    // server.Get(R"(/numbers/(\d+))", Numbers);    // 用 R() 表示圆括号里的都是原始字符
    /*
        正则表达式:
        \,将下一个字符标记
        (),用来捕捉信息
        +,匹配加号前面子表达式一次或多次
    */
    server.Post("/multipart", Multipart);

    server.listen("0.0.0.0", 9090); // IP 这里代表匹配所有的网卡

    return 0;
}
  • bash 中编译代码:
g++ -o server server.cpp -lpthread -std=c++11
  • 运行代码:
./server
  • 借助浏览器,对我们的 server 进行访问 输入

    [server 端公网 IP]\:[端口号]\/[请求]
    

如下:
在这里插入图片描述
在这里插入图片描述

注意:如果浏览器无法加载,是因为端口号被禁了,处理方式如下:

虚拟机 需要关闭防火墙:

sudo systemctl stop firewalld
sudo systemctl disable firewalld

云服务器 需要在官网中设置安全组策略,笔者使用阿里云,界面如下:
在这里插入图片描述


6. 搭建简易 client 客户端

搭建 client.cpp 代码如下:

#include "httplib.h"
#define SERVER_IP "你的server端公网IP"	// 服务器的地址
#define SERVER_PORT 9090                // 服务器的端口号

int main()
{
    httplib::Client clt(SERVER_IP, SERVER_PORT);
    httplib::MultipartFormData item;
    item.name = "filexxx";
    item.filename = "hello.txt";
    item.content = "hello world~~"; // 如果上传的是文件,这里就是文件内容
    item.content_type = "text/plain";

    httplib::MultipartFormDataItems items;
    items.push_back(item);

    auto res = clt.Post("/multipart", items);
    std::cout << res->status << std::endl;
    std::cout << res->body << std::endl;

    return 0;
}
  • bash 中编译代码:
g++ -o client client.cpp -lpthread -std=c++11
  • 在两个会话中,运行代码:
./server
./client
  • 相当于 client 发送了请求,server 收到并传回相应,结果如下:
    在这里插入图片描述

🥰如果本文对你有些帮助,请给个赞或收藏,你的支持是对作者大大莫大的鼓励!!(✿◡‿◡) 欢迎评论留言~~


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

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

相关文章

结构体和联合体

目录 一.结构体 1.1什么是结构体&#xff1f; 1.2结构的声明 1.3特殊声明 1.4结构的自引用 1.5 结构体变量的定义和初始化 1.6 结构体内存对齐 1.7修改默认对齐数 二.联合体 2.1联合类型的定义 2.2联合的特点 2.3联合大小的计算 一.结构体 1.1什么是结构体&#xf…

【milkv】max98357a驱动添加speaker

文章目录 一、电路1.1 duo音频接口1.2 I2S2连接 二、I2S2介绍2.1 参考cv182x的dts实现2.2 参考cv1835_fpga2.3 cv180x2.4 改动——保留i2s2.5 I2S小结 三、参考资料3.1 文章3.2 手册 四、驱动路径五、添加codec驱动——max98357a5.1 config5.2 dtsi5.3 dai_driver 六、查看plat…

VUE3照本宣科——内置指令与自定义指令及插槽

VUE3照本宣科——内置指令与自定义指令及插槽 前言一、内置指令1.v-text2.v-html3.v-show4.v-if5.v-else6.v-else-if7.v-for8.v-on9.v-bind10.v-model11.v-slot12.v-pre13.v-once14.v-memo15.v-cloak 二、自定义指令三、插槽1.v-slot2.useSlots3.defineSlots() 前言 &#x1f…

Chrome之解决DevTools: Failed to load data:No resource with given identifier found

问题 使用DevTools抓包时候, 有些跨域请求无法在加载出来, 提示 Failed to load data:No resource with given identifier found 解决办法 换其他浏览器 下断点 打开DevTools, 选择源代码/来源/Sources,找到事件监听器断点/Event Listener Breakpoints, 找到加载/Load下面…

C++树详解

树 树的定义 树&#xff08;Tree&#xff09;是n&#xff08;n≥0&#xff09;个结点的有限集。n0时称为空树。在任意一颗非空树中&#xff1a;①有且仅有一个特定的称为根&#xff08;Root&#xff09;的结点&#xff1b;②当n>1时&#xff0c;其余结点可分为m&#xff08…

十天学完基础数据结构-第七天(图(Graph))

图的基本概念 图是一种数据结构&#xff0c;用于表示对象之间的关系。它由两个基本组件构成&#xff1a; 顶点&#xff08;Vertex&#xff09;&#xff1a;也被称为节点&#xff0c;代表图中的对象或实体。 边&#xff08;Edge&#xff09;&#xff1a;连接两个顶点的线&…

【setxattr+userfaultfd】SECCON2020-kstack

这个题主要还是练习 userfaultfd 的利用。说实话&#xff0c;userfaultfd 的利用还是挺多的&#xff0c;虽然在新的内核版本已经做了相关保护。 老规矩&#xff0c;看下启动脚本 #!/bin/sh qemu-system-x86_64 \-m 128M \-kernel ./bzImage \-initrd ./rootfs.cpio \-append …

第三章、运输层

文章目录 3.1 概述和运输层服务3.1.1 运输层和网络层的关系3.1.2 因特网运输层概述 3.2 多路复用与多路分解3.3 无连接运输&#xff1a;UDP3.4 可靠数据传输原理3.4.1构造可靠数据传输协议rdt1.0rdt2.xrdt3.0 3.4.2 流水线可靠数据传输协议3.4.3 回退N步3.4.4选择重传 3.5 面向…

x64内核实验1-调试环境配置

x64内核实验1-调试环境配置 这是一套x64内核实验的课程&#xff0c;我之前学习32位内核的时候就是在网上找的各种教程当学完32位很久之后发现在网上的64位内核相关的完整教程真的很少&#xff0c;所以就想着不如自己写一点方便对内核有兴趣的人能更好的入门&#xff0c;首先声…

哈希原理和解决哈希冲突方法

第一 哈希介绍 哈希和红黑树是我早期就听过的名词&#xff0c;却一直没见到真面目&#xff0c;实现哈希后才发现原来我早就使用过了哈希。看下面例题。 用map和set都可以轻松解决&#xff0c;但是在我写这题时我还不会用map和set&#xff0c;我用了另一种方法。看下面代码。先定…

【Java】微服务——Nacos配置管理(统一配置管理热更新配置共享Nacos集群搭建)

目录 1.统一配置管理1.1.在nacos中添加配置文件1.2.从微服务拉取配置1.3总结 2.配置热更新2.1.方式一2.2.方式二2.3总结 3.配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&#xff0c;使用不同的pr…

Office Tool Plus下载与神龙版官网下载

文章目录 一、Office Tool Plus下载二、神龙下载 Office Tool Plus简称OTP&#xff0c;是一款专业的Office官方镜像下载器&#xff0c;可以下载安装Word、Excel、Visio等。神龙用于快速激活使用。 注意&#xff1a;Win7系统必须要SP1或更高版本才能使用&#xff0c;Office Tool…

intel 一些偏门汇编指令总结

intel 汇编手册下载链接&#xff1a;https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html LDS指令&#xff1a; 手册中可以找到 位于 3-588 根据手册内容猜测&#xff1a;lds r16 m16:16 的作用&#xff0c;是把位于 [m16:16] 内存地址的数…

JMeter的详细使用及相关问题

一、中文乱码问题 如果出现乱码&#xff0c;需要修改编码集&#xff0c;&#xff08;版本问题有的不需要修改&#xff0c;就不用管&#xff09; 修改后保存重启就好了。 JMeter5.5版本的按照如下修改&#xff1a; 二、JMeter的启动 ①建议直接用ApacheJMeter.jar双击启动…

Zabbix4自定义脚本监控MySQL数据库

一、MySQL数据库配置 1.1 创建Mysql数据库用户 [rootmysql ~]# mysql -uroot -p create user zabbix127.0.0.1 identified by 123456; flush privileges; 1.2 添加用户密码到mysql client的配置文件中 [rootmysql ~]# vim /etc/my.cnf.d/client.cnf [client] host127.0.0.1 u…

CSDN博主粉丝数突破10万:坚持分享的力量与收获

今天&#xff0c;我在CSDN上看到了一位好友的统计数据&#xff0c;他统计了CSDN上所有粉丝数量排名靠前的博主的排名。虽然这个统计可能存在一些误差&#xff0c;但大体上应该是准确的。我惊讶地发现&#xff0c;截止到2023年10月4日&#xff0c;我的粉丝数量已经达到了101,376…

QScrollArea样式

QScrollBar垂直滚动条分为sub-line、add-line、add-page、sub-page、up-arrow、down-arrow和handle几个部分。 QScrollBar水平滚动条分为sub-line、add-line、add-page、sub-page、left-arrow、right-arrow和handle几个部分。 部件如下图所示&#xff1a; /* 整个滚动…

Pikachu靶场——文件包含漏洞(File Inclusion)

文章目录 1. File Inclusion1.2 File Inclusion(local)1.2.1 源代码分析1.2.2 漏洞防御 1.3 File Inclusion(remote)1.3.1 源代码分析1.3.2 漏洞防御 1.4 文件包含漏洞防御 1. File Inclusion 还可以参考我的另一篇文章&#xff1a;文件包含漏洞及漏洞复现。 File Inclusion(…

商业智能系统的主要功能包括数据仓库、数据ETL、数据统计输出、分析功能

ETL服务内容包含&#xff1a; 数据迁移数据合并数据同步数据交换数据联邦数据仓库

plt 画图不显示label

没写 plt.legend() 这个 ! # 效果模拟-------------- import matplotlib.pyplot as plt import matplotlib as mpl # matplotlib其实是不支持显示中文的 显示中文需要一行代码设置字体 mpl.rcParams[font.family] = STKAITI # STKAITI——字体 plt.rcParams[axes.unicode_m…