云备份day03

news2025/1/19 11:33:27

📟作者主页:慢热的陕西人

🌴专栏链接:C++云备份项目

📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言

主要内容介绍了第三方库httplib的一些内容,以及实现了一个简单的CS例子

在这里插入图片描述

文章目录

  • 云备份day03
    • 1.httplib库
    • 2.httplib实现server和client
      • 2.1httplib实现server端
      • 2.2httplib实现client端

云备份day03

1.httplib库

httplib 库,一个 C++11 单文件头的跨平台 HTTP/HTTPS 库。安装起来非常容易。只需包含 httplib.h 在你的代码
中即可。
httplib 库实际上是用于搭建一个简单的 http 服务器或者客户端的库,这种第三方网络库,可以让我们免去搭建服
务器或客户端的时间,把更多的精力投入到具体的业务处理中,提高开发效率。

namespace httplib
{
    struct MultipartFormData
    {
        std::string name;
        std::string content;
        std::string filename;
        std::string content_type;
    };
    using MultipartFormDataItems = std::vector<MultipartFormData>;
    
    struct Request
    {
        std::string method; //请求方法
        std::string path;   //url
        Headers headers;    //头部字段
        std::string body;   //正文->有效载荷
        // for server
        std::string version;//协议版本
        Params params;	    //查询字符串
        MultipartFormDataMap files;//保存的是客户端上传文件的信息
        Ranges ranges;      //用于实现断点续传的文件请求的区间
        bool has_header(const char *key) const;
        std::string get_header_value(const char *key, size_t id = 0) const;
        void set_header(const char *key, const char *val);
        bool has_file(const char *key) const;
        MultipartFormData get_file_value(const char *key) const;
    };
    struct Response	
    {
        std::string version;   //协议版本
        int status = -1;	  //响应状态码
        std::string reason;   //
        Headers headers;	  //头部字段
        std::string body;	  //响应给客户端的正文
        std::string location; // Redirect location
        void set_header(const char *key, const char *val); //设置头部字段
        void set_content(const std::string &s, const char *content_type); //设置正文
    };
    
    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; //线程池---用于处理请求
        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);
        bool listen(const char *host, int port, int socket_flags = 0); //搭建并启动http服务器
    };
	//用于搭建http客户端
    class Client
    {
        Client(const std::string &host, int port); //传入服务器的ip地址和端口
        Result Get(const char *path, const Headers &headers); //向服务器发送get请求
        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请求提交多区域数据,常用于多文件上传
    }
}
  • Request

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

  • Response

    Response结构体的作用:
    用户将响应数据放到结构体中,httplib会将其中的数据按照http响应的格式组织成http响应
    然后发送给客户端

  • Server:

    server类的功能:用于搭建http的服务器

    **1.hander 函数指针类型:**定义了一个http请求处理回调函数的方式
    函数指针类型:定义了一个http请求处理回调函数格式httplib搭建的服务器收到请求后,进行解析,得到一Reques结构体:

    其中包含了请求数据根据请求数据我们就可以处理这个请求了,这个处理函数定义的格式就是Handler格式
    void(const Request &,Response &)
    Request参数,1保存请求数据,让用户能够根据请求数据进行业务处理。
    Response参数,需要用户在业务处理中,填充数据,最终要响应给客户端
    2.Handlers 是一个请求路由数组:
    其中包含两个信息std::vector<std::pair<std::regex,Handler>>
    regex:正则表达式-用于匹配http请求资源路径
    Handler:请求处理函数指针可以理解,Handlers是一张表,映射了一个客户端请求的资源路径和一个处理函数(用户自己定义的函数)
    当服务器收到请求解析得到Request就会根据资源路径以及请求方法到这张表中查看有没有对应的处理函数
    如果有则调用这个函数进行请求处理,无则响应404.

    **处理流程:**线程池,处理http请求

    httplib收到一个新建链接,则将新的客户端连接抛入到线程池中

    线程池中线程的工作:

    ​ ①接收请求,解析请求,得到Request结构体也就是请求的数据

    ​ ②在Handlers映射表中,根据请求信息查找处理函数,如果有则调用函数处理
    void(const Request &, Response &)

    ​ ③当处理函数调用完毕根据函数返回的Response结构体中的数据组织http响应发送给客户端

2.httplib实现server和client

2.1httplib实现server端

#include"httplib.h"

using namespace std;
using namespace httplib;

// 处理 "/hi" 路径的 GET 请求,返回 "hello_world!"
void Hello(const Request& req, Response& rsp)
{
    rsp.set_content("hello_world!", "text/plain");
    rsp.status = 200;
}

// 处理 "/numbers/{num}" 路径的 GET 请求,返回匹配到的数字
void Numbers(const Request& req, Response& rsp)
{
    auto num = req.matches[1]; // 0 保存的是整体的 path,往后的下标中保存的是数据
    rsp.set_content(num, "text/plain");
    rsp.status = 200;
}

// 处理 "/multipart" 路径的 POST 请求,返回上传的文件名和内容
void Multipart(const Request& req, Response& rsp)
{
    auto ret = req.has_file("file");
    if (ret == false)
    {
        cout << "not file upload" << endl;
        rsp.status = 400;
        return;
    }

    const auto& file = req.get_file_value("file");
    rsp.body.clear();
    rsp.body = file.filename; // 文件名称
    rsp.body += "\n";
    rsp.body += file.content; // 文件内容
    rsp.set_header("Content-Type", "text/plain");
    rsp.status = 200;
    return;
}

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

    server.Get("/hi", Hello); // 注册一个针对 "/hi" 的 GET 请求的处理函数映射关系
    server.Get(R"(/numbers/(\d+))", Numbers); 
    server.Post("/multipart", Multipart);
    server.listen("0.0.0.0", 9090);
    return 0;
}

2.2httplib实现client端

#include"httplib.h"  // 引入 httplib 库的头文件

using namespace std;  // 使用标准命名空间

#define SERVER_IP "117.72.37.100"  // 定义服务器 IP 地址常量
#define SERVER_PORT 9090  // 定义服务器端口号常量

int main()
{
    // 实例化一个 httplib 客户端对象,并指定服务器的 IP 地址和端口号
    httplib::Client client(SERVER_IP, SERVER_PORT);

    // 创建一个多部分表单数据项
    httplib::MultipartFormData item;
    item.name = "file";  // 表单项的名称
    item.filename = "hello.text";  // 文件名
    item.content = "hello world";  // 文件内容
    item.content_type = "text/plain";  // 文件内容类型

    // 创建一个多部分表单数据项列表,并将上面创建的表单项添加到列表中
    httplib::MultipartFormDataItems items;
    items.push_back(item);

    // 向服务器发送 POST 请求,提交多部分表单数据
    auto res = client.Post("/multipart", items);

    // 输出服务器响应的状态码和响应体
    cout << res->status << endl;  // 打印响应状态码
    cout << res->body << endl;    // 打印响应体内容
    
    return 0;
}

到这本篇博客的内容就到此结束了。
如果觉得本篇博客内容对你有所帮助的话,可以点赞,收藏,顺便关注一下!
如果文章内容有错误,欢迎在评论区指正

在这里插入图片描述

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

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

相关文章

「 典型安全漏洞系列 」10.跨域资源共享CORS漏洞详解

跨域资源共享&#xff08;Cross-origin Resource Sharing&#xff0c;CORS&#xff09;是一种浏览器机制&#xff0c;可以对于给定域之外的资源进行受控访问。它扩展并增加了同源政策&#xff08;Same-origin Policy&#xff0c;SOP&#xff09;的灵活性。然而&#xff0c;如果…

蓝鲸6.1 CMDB 事件推送的开源替代方案

本文来自腾讯蓝鲸智云社区用户&#xff1a;木讷大叔爱运维 背景 在蓝鲸社区“社区问答”帖子中发现这么一个需求&#xff1a; 究其原因&#xff0c;我在《不是CMDB筑高墙&#xff0c;运维需要一定的开发能力&#xff01;》一文中已经介绍&#xff0c;在此我再简单重复下&#…

吴恩达机器学习笔记:第 6 周-11机器学习系统的设计(Machine Learning System Design)11.1-11.5

目录 第 6 周 11、 机器学习系统的设计(Machine Learning System Design)11.1 首先要做什么11.2 误差分析11.3 类偏斜的误差度量11.4 查准率和查全率之间的权衡11.5 机器学习的数据 第 6 周 11、 机器学习系统的设计(Machine Learning System Design) 11.1 首先要做什么 在接…

Docker简单介绍、特点、与虚拟机技术的区别、核心概念及在CentOS 7 中安装卸载Docker

目录 一、什么是Docker 二、特点 三、Docker与虚拟机技术的区别 四、Docker的核心概念 Docker仓库与仓库注册服务器的区别 五、CentOS7在线安装Docker 安装配置 卸载 一、什么是Docker Docker是一个开源的容器化平台&#xff0c;用于打包、部署和运行应用程序。它利用…

移动端适配方案总结之vw

1、vw/vh是什么&#xff1f; vw是&#xff1a;viewport width 视口宽度单位 vh是&#xff1a; viewport height 视口高度单位 实际开发中我们基本用vw&#xff1b; 2.相对视口的尺寸计算结果 1vw 1/100视口宽度 1vh 1/100视口高度 例如&#xff1a; 当前屏幕视口是 375像素…

聚类算法的先验基础知识

聚类算法的先验基础知识 1. 瑞利商2. 谱定理3. 联合概率4. 条件概率分布5. 边缘分布6. 贝叶斯定理7. 有向图8. 拉格朗日乘子定理 下一篇将介绍整理各种聚类算法&#xff0c;包括k-means&#xff0c;GMM(Guassian Mixture Models, 高斯混合)&#xff0c;EM(Expectation Maximiza…

如果真的要被优化了,你该如何提前应对与准备!

程序员35岁会失业吗&#xff1f; 35岁被认为是程序员职业生涯的分水岭&#xff0c;许多程序员开始担忧自己的职业发展是否会受到年龄的限制。随着科技的飞速发展&#xff0c;IT行业成为了变化最为迅速的领域之一。在这样的背景下&#xff0c;许多35岁左右的程序员开始担忧自己…

Android数据存储技术

一、文件存储 <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:orientation"vertical"android:layout_width"match_parent"android:layout_height"match_parent" ><EditTextandroid:id&qu…

【C++】c++11新特性(一)

目录 { }列表初始化 内置类型---对单值变量及数组的初始化 列表初始化时进行的类型转换 自定义类型---对类对象或结构的初始化 initializer_list 1. 定义接受 initializer_list 参数的构造函数 2. 在函数中使用 initializer_list 参数 3. 使用 initializer_list 与 vect…

C#将Console写至文件,且文件固定最大长度

参考文章 将C#的Console.Write同步到控制台和log文件输出 业务需求 在生产环境中&#xff0c;控制台窗口不便展示出来。 为了在生产环境中&#xff0c;完整记录控制台应用的输出&#xff0c;选择将其输出到文件中。 但是&#xff0c;一次性存储所有输出的话&#xff0c;文件会…

基于SSM+Jsp+Mysql的二手车交易网站

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

5G智慧地铁数字孪生可视化平台,推进铁路行业数字化转型

随着科技的快速发展&#xff0c;5G智慧地铁数字孪生可视化平台正逐渐成为铁路行业数字化转型的重要推动力。巨蟹数科数字孪生平台集成了5G通信技术、大数据分析、云计算和人工智能等先进技术&#xff0c;通过构建数字孪生模型&#xff0c;实现对地铁运营全过程的实时监控、预测…

【智能排班系统】基于SpringSecurity实现登录验证、权限验证

文章目录 SpringSecurity介绍sss-security实现依赖工具类Jwt工具JSON响应工具加密工具类 用户上下文用户信息实体类用户上下文 自定义重写自定义无权限的报错自定义密码加密自定义用户类 过滤器登录过滤器权限过滤器 Service登录Service 配置类说明登录验证权限验证IP流量限制 …

JDK安全剖析之安全处理入门

0.前言 Java 安全包括大量 API、工具以及常用安全算法、机制和协议的实现。Java 安全 API 涵盖了广泛的领域&#xff0c;包括加密、公钥基础设施、安全通信、身份验证和访问控制。Java 安全技术为开发人员提供了编写应用程序的全面安全框架&#xff0c;还为用户或管理员提供了…

蓝桥集训之斐波那契数列

蓝桥集训之斐波那契数列 核心思想&#xff1a;矩阵乘法 将原本O(n)的递推算法优化为O(log2n) 构造1x2矩阵f和2x2矩阵a 发现f(n1) f(n) * a 则f(n1) f(1) * an可以用快速幂优化 #include <iostream>#include <cstring>#include <algorithm>using na…

跨站请求伪造漏洞(CSRF)

什么是CSRF CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;也被称为 one-click attack 或者 session riding&#xff0c;即跨站请求伪造攻击。 漏洞原理 跨站请求伪造漏洞的原理主要是利用了网站对用户请求的验证不严谨。攻击者会在恶意网站中构造一个…

RAG知识分享

文章目录 博客详细讲解视频点击查看高清脑图 1.为什么要做RAG1.1. 解决幻觉问题1.1.1 直接输入问题1.1.2. 问题 相关知识 2. 什么是RAG2.1. 基本概念2.2. 基本RAG方法2.2.1. 知识预处理2.2.2. 知识检索2.2.3. 答案生成 3. RAG 与 Long Context3.1. Long Context3.2. RAG 与Lon…

你为什么选择程序员这个职业?

注意&#xff0c;今天的这篇文章&#xff0c;我只是对程序员这份工作所需要面对的问题挑选一些有意思的话题讲讲我的理解&#xff0c;并不是对程序员的职业规划进行分享。本文分为入行前和入行后两个部分&#xff0c;分别聊聊。 入行前 所谓入行前&#xff0c;其实就是指还是学…

力扣面试150: O(1) 时间插入、删除和获取随机元素 HashMap结合数组

Problem: 380. O(1) 时间插入、删除和获取随机元素 文章目录 思路复杂度Code 思路 &#x1f469;‍&#x1f3eb; 三叶题解 复杂度 时间复杂度: O ( 1 ) O(1) O(1) 空间复杂度: O ( n ) O(n) O(n) Code class RandomizedSet {static int[] nums new int[200_010];//存…

RabbitMQ小记

参考书籍&#xff1a;朱忠华的《RabbitMQ实战指南》 一、基础概念 1.Exchange 1.1 创建方法的参数&#xff0c;exchangeDeclare() exchange&#xff1a;交换器的名称type&#xff1a;交换器的类型durable&#xff1a;是否持久化&#xff0c;true代表持久化。&#xff08;持…