【云备份】httplib库

目录

1.httplib库简介

2.httplib请求类

 3.httplib响应类

4.Server类

5.Client类

6.httplib库搭建简单服务器

6.1.ubuntu20.04使用防火墙开放端口

6.2.效果

7.httplib库搭建简单服务器


 

注意:如果对HTTP不熟悉就去:【网络】HTTP_yum install telnet-CSDN博客 

在当今的软件开发中,与网络通信相关的任务变得日益普遍。HTTP(Hypertext Transfer Protocol)作为互联网通信的核心协议之一,扮演着连接客户端与服务器的桥梁。为了简化开发人员对HTTP的处理,httplib 库应运而生。这个C++库提供了简单且高效的方法来创建HTTP服务器和客户端,使得开发人员能够更加轻松地构建Web应用程序、微服务和网络连接的应用。本文将深入探讨httplib库的特性、用法以及如何在C++项目中集成它,帮助读者更好地理解和利用这个强大的工具。 

1.httplib库简介

httplib 是一个轻量级的 C++ 库,用于创建 HTTP 服务器和客户端。它的设计简单而灵活,非常容易设置。只需在代码中包含 httplib.h 文件即可!使得开发者能够在自己的 C++ 项目中轻松地实现基本的 HTTP 通信功能。

特性说明
简单易用的接口httplib 提供了简单易用的接口,使得创建 HTTP 服务器和客户端变得非常容易。通过少量的代码,你就能够建立起一个功能完善的 HTTP 服务器或客户端。
支持主要 HTTP 方法httplib 支持主要的 HTTP 方法,包括 GET、POST、PUT、DELETE 等,让你能够处理各种类型的 HTTP 请求。
灵活的路由处理使用 httplib,你可以轻松地定义路由和处理函数,根据不同的 URL 请求调用相应的处理函数。这使得构建 RESTful API 或者 Web 应用程序变得非常方便。
支持静态文件服务httplib 还提供了静态文件服务的功能,你可以将指定目录下的文件直接暴露给客户端访问,而无需额外处理。
简洁的代码库httplib 的代码库非常简洁,没有过多的依赖,易于集成到你的项目中。这使得它成为了许多开发者选择的首选 HTTP 库之一。
活跃的开发和社区支持httplib 的开发仍在持续进行中,它的代码库得到了广大开发者社区的支持和贡献,因此可以期待它会持续改进和更新。

总的来说,httplib 是一个功能强大且易于使用的 C++ HTTP 库,适用于各种类型的项目,无论是小型工具还是大型 Web 应用程序。通过它,你可以快速地搭建起自己的 HTTP 服务器或客户端,实现各种网络通信需求。

2.httplib请求类

还记得HTTP请求报头吗

httplib中封装了一个结构——Request,用来保存客户端/浏览器发送的HTTP请求的内容。当服务器获取到客户端的请求,httplib会将请求字符串解析成Request

struct Request {//成员变量std::string method;//请求方法std::string path;//请求资源路径——URLHeaders headers;//头部字段std::string body;//正文部分std::string version;//协议版本Params params;//查询字符串MultipartFormDataMap files;//客户端上传文件的信息Ranges ranges;//实现断点续传的请求区间//提供的API//查询头部字段key是否存在bool has_header(const char *key) const;//获取头部字段的valuestd::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 MultipartFormData {std::string name;//字段名称std::string content;//文件内容std::string filename;//文件名std::string content_type;//文件类型
};
//文件结构体数组
using MultipartFormDataItems = std::vector<MultipartFormData>;

 3.httplib响应类

大家应该都记得http响应报头吧

httplib响应类是Responce,需要用户手动填补,httplib返回响应时,会将Responce组织成字符串返回给客户端

struct Response {std::string version;   //协议版本号,默认时http1.1int status = -1;       //响应状态码,std::string reason;    Headers headers;       //响应报头std::string body;      //响应正文std::string location; // 重定向位置
//两个比较重要的API
//以key-val将相应的字段设定到响应报头中
void set_header(const char *key, const char *val);
//设置正文——可以设置类型
void set_content(const std::string &s, const char *content_type);
};

4.Server类

Server类就是httplib中用于搭建服务器的类

class Server {//Handler一个函数指针,它的返回值为void,参数是Request,和Responseusing Handler = std::function<void(const Request &, Response &)>;//Handlers是一个映射表,将请求资源和处理函数映射在一起using Handlers = std::vector<std::pair<std::regex, Handler>>;//将Get方法的请求资源与处理函数加载到Handlers表中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);//线程池std::function<TaskQueue *(void)> new_task_queue;//搭建并启动httpbool listen(const char *host, int port, int socket_flags = 0);};

首先,Handler是一个回调的函数指针。Handlers是一个映射表。std::regex是正则表达式,用于匹配请求资源,即URL中的path。Handlers将请求的资源和处理函数进行映射。当服务器收到一个请求,解析Request,获取客户端请求的资源路径,在Handlers表中找是否存在映射关系,有则调用对应的Handler回调函数处理请求,无则返回404(请求资源不存在)。

上面的Get,Post,Put,Patch,Delete,Options都是往Handlers表中设置映射关系

请求方法,请求资源和处理函数都是强相关的,如上表:

  1. 只有http请求的请求方法是GET,且请求的资源是/Hello/a,服务器才会调用echoHelloA处理请求
  2. 只要请求方法和请求资源在Handlers表中找不到映射的处理函数,http服务器就会返回404的http响应,表示请求资源不存在
  3. Get("/Hello/a", echoHelloA):将请求方法为GET,请求资源为/Hello/a,与函数echoHelloA注册到Handlers表中

线程池的工作:

  1. 当服务器接收到一个http请求,会将该http请求放入线程池,线程池的线程会调用相应的函数解析http请求,形成一个Request对象
  2. 在Handlers映射表中查找有无对应请求方法和请求资源的处理函数,有则调用处理函数,并构建http响应
  3. 处理函数调用完后,将Responce构建成http响应,并将构建好的http响应返回给客户端

5.Client类

class Client {//构造一个客户端对象,传入服务器Ip地址和端口Client(const std::string &host, int port);//向服务器发送GET请求Result Get(const char *path, const Headers &headers);//向服务器发送Post请求//path是路径,body是request请求路径//content_length是正文大小//content_type是正文的类型Result Post(const char *path, const char *body, size_t content_length,const char *content_type);//以Post方法上传文件Result Post(const char *path, const MultipartFormDataItems &items);
}

6.httplib库搭建简单服务器

搭建服务器:

  1. 定义server对象
  2. 在Handlers表中注册相应请求方法和请求资源的处理函数
  3. listen绑定IP地址和端口号,启动服务器,监听连接和请求

main.cc(函数版本)

#include <iostream>
#include "httplib.h"
using namespace httplib;
void Hello(const Request &req, Response &rsp)
{   rsp.set_content("Hello World!", "text/plain");rsp.status = 200; // 设置状态码
}
void Numbers(const Request &req, Response &rsp)
{   auto num = req.matches[1]; // 0里边保存的是整体path,往后下标中保存的是捕捉的数据rsp.set_content(num, "text/plain");rsp.status = 200;
}
void Multipart(const Request &req, Response &rsp)
{auto ret = req.has_file("file");if(ret == false){std::cout << "not file upload\n";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()
{httplib::Server sever; // 实例化Sever对象用于搭建服务器sever.Get("/hi", Hello); // 注册一个针对/hi的Get请求的处理函数映射关系sever.Get(R"(/numbers/(\d+))", Numbers);sever.Post("/multipart", Multipart);sever.listen("0.0.0.0", 9090);return 0;
}

main.cc(正则表达式版本) 

#include <iostream> // 引入标准输入输出流库  
#include "httplib.h" // 引入httplib库,用于创建HTTP服务器  
#include <string> // 引入字符串库  int main()  
{  httplib::Server server; // 创建一个httplib的Server对象,用于启动HTTP服务器  // 设置处理函数  // GET请求方法,/hello请求资源的映射函数  server.Get("/hello", [](const httplib::Request& req, httplib::Response& resp){  resp.set_content("Hello World!", "text/plain"); // 设置响应内容为"Hello World!",并指定内容类型为文本  resp.status = 200; // 设置HTTP响应状态码为200,表示请求成功  });  // GET请求方法,/number/数字请求资源的映射函数  // 使用原始字符串字面量来避免转义字符的问题,(\d+)用于捕获数字  server.Get(R"(/number/(\d+))", [](const httplib::Request& req, httplib::Response& resp){  // matches[0]是完整请求资源路径,matches[1]是第一个(也是唯一一个)捕获的参数,即数字  auto num = req.matches[1]; // 从请求匹配中获取捕获的数字  resp.set_content(num, "text/plain"); // 将捕获的数字作为响应内容,并指定内容类型为文本  resp.status = 200; // 设置HTTP响应状态码为200,表示请求成功  });  // POST请求方法,/upload请求资源的映射函数  server.Post("/upload", [](const httplib::Request& req, httplib::Response& resp){  auto ret = req.has_file("file"); // 检查请求中是否包含名为"file"的文件  if(ret == false) // 如果没有上传文件  {  resp.set_content("没有上传file文件", "text/plain"); // 设置响应内容为提示信息,并指定内容类型为文本  resp.status = 404; // 设置HTTP响应状态码为404,表示请求的资源未找到(这里可以视为未找到上传的文件)  return -1; // 返回-1,表示处理函数执行失败(但在这个例子中,返回值并没有被使用)  }  auto size = req.files.size(); // 获取上传文件的数量(虽然在这个例子中我们只关心一个文件)  const auto& file = req.get_file_value("file"); // 获取上传的文件信息(MultipartFormData结构体)  // 构建响应内容  resp.body.clear(); // 清空响应体  resp.body = file.filename; // 将文件名添加到响应体中  resp.body += "\n"; // 添加换行符  resp.body += file.content; // 将文件内容添加到响应体中  resp.set_header("Content-Type", "text/plain"); // 设置响应头,指定内容类型为文本  resp.status = 200; // 设置HTTP响应状态码为200,表示请求成功  });  // 启动服务器,绑定到所有可用的IP地址(0.0.0.0)和指定的端口号(8080)  server.listen("0.0.0.0", 8080); // 这将阻塞当前线程,直到服务器被关闭  return 0; // 程序正常结束,返回0  
}

以下是该程序的执行过程详解:

创建HTTP服务器:

  • 在main函数内部,首先创建了一个httplib::Server对象。这个对象代表了一个HTTP服务器,它将负责监听和处理来自客户端的请求。

设置路由和处理函数:程序通过调用server.Get和server.Post方法为HTTP服务器设置了路由和处理函数。

  • 对于/hello路由,当收到GET请求时,服务器将返回"Hello World!"作为响应。
  • 对于/number/(\d+)路由,当收到GET请求并匹配到一个数字时,服务器将返回该数字作为响应。这里使用了正则表达式\d+来匹配一个或多个数字。
  • 对于/upload路由,当收到POST请求并包含名为"file"的文件时,服务器将返回该文件的名字和内容作为响应。

启动服务器:

  • 程序通过调用server.listen("0.0.0.0", 8080)来启动服务器。这里,"0.0.0.0"表示服务器将监听所有可用的网络接口,8080是服务器监听的端口号。
  • listen函数将阻塞当前线程,等待客户端的连接和请求。这意味着在服务器运行期间,程序将停留在这一步,直到服务器被外部方式关闭(如通过发送终止信号或手动停止程序)。

处理客户端请求:

  • 当有客户端向服务器发送请求时(例如,通过浏览器访问http://<服务器IP>:8080/hello),服务器将根据请求的URL和方法(GET、POST等)找到相应的处理函数。
  • 处理函数将被调用,并接收两个参数:一个表示请求信息的httplib::Request对象和一个用于构建响应的httplib::Response对象。
  • 处理函数根据请求的内容生成响应,并通过修改httplib::Response对象来设置响应的内容、状态码和头部信息。
  • 最后,服务器将响应发送回客户端。

编译

 首先我们要把那个httplib.h搞出来

然后我们通过下面这个编译即可

g++ -o server main.cc -std=c++14 -lpthread

 

接下来就能开始我们的测试了 


6.1.ubuntu20.04使用防火墙开放端口

在Ubuntu 20.04中,默认使用的是ufw(Uncomplicated Firewall)作为防火墙管理工具。    

使用ufw(默认防火墙管理工具)

打开防火墙

sudo ufw enable

关闭防火墙

sudo ufw disable 

查看防火墙状态

sudo ufw status

开放TCP端口

 sudo ufw allow 80/tcp # 开放TCP 80端口  sudo ufw allow 443/tcp # 开放TCP 443端口  sudo ufw allow 3306/tcp # 开放TCP 3306端口  sudo ufw allow 6379/tcp # 开放TCP 6379端口 


关闭TCP端口

 sudo ufw deny 80/tcp # 关闭TCP 80端口  sudo ufw deny 443/tcp # 关闭TCP 443端口  sudo ufw deny 3306/tcp # 关闭TCP 3306端口  sudo ufw deny 6379/tcp # 关闭TCP 6379端口 


开放UDP端口

sudo ufw allow 9595/udp # 开放UDP 9595端口

 关闭UDP端口

sudo ufw deny 9595/udp # 关闭UDP 9595端口 

查看监听的TCP端口

sudo netstat -ntlp 

查看监听的UDP端口

sudo netstat -nulp 

查看所有开放的端口

sudo ufw status numbered

检测UDP的特定端口是否开放

# ufw没有直接的查询端口是否开放的命令,但你可以通过查看状态来确认  
sudo ufw status numbered | grep 9595 

检测TCP的特定端口是否开放

 # 同上,通过查看状态来确认  
sudo ufw status numbered | grep 80 

对于ufw,通常命令执行后即时生效,不需要额外命令来使配置生效,ufw命令执行后即时生效  


 我们先打开防火墙,并且查看状态

 

接着我们开放8080端口

sudo ufw allow 8080/tcp

 

接着我们可以看看有没有开放成功

sudo ufw status numbered | grep 8080

 

开放成功了!!

 注意:除了防火墙要开放端口外,还要在云服务器官网设置安全组

不懂的可以看这个:【网络】套接字(socket)编程——UDP版_udp 命名socket-CSDN博客

6.2.效果

我们可以来试一试效果

这个程序是一个基于httplib库的简单HTTP服务器,它能够处理特定路由上的GET和POST请求。以下是它能处理的客户端请求类型:
GET请求:

  1. /hello:当客户端向服务器发送GET请求到/hello路由时,服务器将返回文本内容"Hello World!"。
  2. /number/(\d+):这是一个带有正则表达式的路由,用于匹配形如/number/123的URL,其中123可以是任意数字。当匹配成功时,服务器将返回该数字作为文本内容。

POST请求:

  • /upload:当客户端向服务器发送POST请求到/upload路由,并且请求中包含名为"file"的文件时,服务器将处理该文件上传。服务器将返回上传文件的文件名和文件内容作为文本响应。

需要注意的是,这个程序只能处理上述特定路由上的请求。如果客户端发送请求到未定义的路由,服务器将不会返回任何响应(或者根据httplib的默认行为,可能会返回一个404错误)。

 

7.httplib库搭建简单服务器

简单客户端

  1. 定义Clinet对象,绑定要连接的服务器的IP地址和端口号
  2. 构建请求
  3. 获取响应,处理响应
#include <iostream>
#include <string>
#include "httplib.h"int main()
{//连接服务器httplib::Client client("121.36.254.82", 8080);//构建文件结构体httplib::MultipartFormData item;item.name = "file";item.filename = "Hello.txt";item.content = "Hello World!";item.content_type = "text/plain";//文件结构体数组——传输多个文件httplib::MultipartFormDataItems items;items.push_back(item);//发送请求auto res = client.Post("/upload", items);//接收并处理响应std::cout << res->status << std::endl;std::cout << res->body << std::endl;
}

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

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

相关文章

【CENet】多模态情感分析的跨模态增强网络

在MSA领域&#xff0c;文本的准确度远远高于音频和视觉&#xff0c;如果文本能达到90%&#xff0c;那么音频和视觉的准确度只有60%~80%&#xff0c;但是过往研究很少针对情感分析的背景下去提高音频和视频的准确度。 abstract&#xff1a; 多模态情感分析&#xff08;MSA&…

多线程--模拟实现定时器--Java

一、定时器的概念 定时器的本质就是一个闹钟&#xff0c;时间到了开始执行某些逻辑。Java标准库中的定时器是Timer。 我们查阅Java文档可以详细看到定时器的使用方法&#xff1a; Timer最核心的方法就是schedule方法。值得注意的是我们通常描述任务是使用Runnable来描述&…

‌MySQL中‌between and的基本用法‌

文章目录 一、between and语法二、使用示例2.1、between and数值查询2.2、between and时间范围查询2.3、not between and示例 BETWEEN AND操作符可以用于数值、日期等类型的字段&#xff0c;包括边界值。 一、between and语法 MySQL中的BETWEEN AND操作符用于在两个值之间选择…

视频一键转换3D:Autodesk 发布 Video to 3D Scene

Video 3D Scene 最近 Autodesk 旗下公司 Wonder Dynamics 推出了 Wonder Animation 的测试版&#xff0c;它使用突破性的视频到 3D 场景技术&#xff0c;通过将任何视频序列转换为 3D 动画场景来加速动画电影的制作。 Video 3D Scene Video 3D Scene 生成效果 作为 Wonder Stud…

数据结构 C/C++(实验一:线性表)

&#xff08;大家好&#xff0c;今天分享的是数据结构的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 提要&#xff1a;实验题目 一、实验目的 二、实验内容及要求 三、算法思想 实验1 实验2 四、源程序及注释 …

关于SQLServer在局域网内无法连接的问题的解决思路

针对SQL Server 2008在局域网内无法连接的问题&#xff0c;以下是一些详细的解决办法。我们在过程中需要用到Microsoft SQL Server 2008和Microsoft SQL Server tools 2008数据库软件中的配置管理器以及SQL Server Management Studio工具&#xff0c;入下截图所示。 一、检查网…

【C++】RBTree——红黑树

文章目录 一、红黑树的概念1.1 红⿊树的规则&#xff1a;1.2 理解最长路径长度不超过最短路径长度的 2 倍1.3 红⿊树的效率 二、 红⿊树的实现2.1 红⿊树的结构2.2 红⿊树的插⼊2.2.1 红⿊树树插⼊⼀个值的⼤概过程 2.3 红⿊树的插⼊代码实现 一、红黑树的概念 红⿊树是⼀棵⼆…

Docker-- cgroups资源控制实战

上一篇&#xff1a;容器化和虚拟化 什么是cgroups&#xff1f; cgroups是Linux内核中的一项功能&#xff0c;最初由Google的工程师提出&#xff0c;后来被整合进Linux内核; 它允许用户将一系列系统任务及其子任务整合或分隔到按资源划分等级的不同组内&#xff0c;从而为系统…

vscode ssh连接autodl失败

autodl服务器已开启&#xff0c;vscode弹窗显示连接失败 0. 检查状态 这里的端口和主机根据自己的连接更改 ssh -p 52165 rootregion-45.autodl.pro1. 修改config权限 按返回的路径找到config文件 右键--属性--安全--高级--禁用继承--从此对象中删除所有已继承的权限--添加…

你适合哪种tiktok广告账户类型?

TikTok在广告营销方面的分类体系极为详尽。在开设广告账户时&#xff0c;根据不同的海外市场和商品类型&#xff0c;TikTok会有各自的开户标准。此外&#xff0c;广告主所开设的TikTok广告账户类型会直接影响其可投放的广告类型。在广告出价方面&#xff0c;广告主的营销目标不…

大规模语言模型:从理论到实践(1)

1、绪论 大规模语言模型&#xff08;Large Language Models&#xff0c;LLM&#xff09;是由包含数百亿以上参数的深度神经网络构建的语言模型&#xff0c;采用自监督学习方法通过大量无标注文本进行训练。自2018年以来&#xff0c;多个公司和研究机构相继发布了多种模型&#…

SpringBoot中@Validated或@Valid注解校验的使用

文章目录 SpringBoot中Validated或Valid注解校验的使用1. 添加依赖2. 使用示例准备2-1 测试示例用到的类2-2 实体Dto&#xff0c;加入校验注解2-2 Controller 3. 示例测试4. Valid 和 Validated注解详解4-1 常用规则注解4-2 分组验证4-2-1 示例准备4-2-2 Controller接口4-2-3 P…

HarmonyOS使用arkTS拉起指定第三方应用程序

HarmonyOS使用arkTS拉起指定第三方应用程序 前言代码及说明bundleName获取abilityName获取 前言 本篇只说采用startAbility方式拉起第三方应用&#xff0c;需要用到两个必备的参数bundleName&#xff0c;abilityName&#xff0c;本篇就介绍如何获取参数… 代码及说明 bundle…

04_CC2530+Uart串口通信

04_CC2530UART串口通信 串口通信基本概念 串行通信: 数据字节一位位地依次传送的通信方式, 串行通信的速度慢, 但用的传输线条数少, 成本低&#xff0c;适用于远距离的数据传送并行通信: 数据字节的各位同事传送的通信方式, 优点是数据传送速度快, 缺点是占用的传输线条数多,…

Speaker Recognition说话人识别(声纹识别)

说话人识别&#xff0c;又称声纹识别。从上世纪60年代开始到现在&#xff0c;声纹识别一直是生物识别技术研究的主题。从传统的基于模板匹配的方法&#xff0c;到早期基于统计学方法&#xff0c;直到基于深度学习的声纹识别技术成为主流。本项目给出一个从传统&#xff08;基于…

SpringBoot篇(简化操作的原理)

目录 一、代码位置 二、统一版本管理&#xff08;parent&#xff09; 三、提供 starter简化 Maven 配置 四、自动配置 Spring&#xff08;引导类&#xff09; 五、嵌入式 servlet 容器 一、代码位置 二、统一版本管理&#xff08;parent&#xff09; SpringBoot项目都会继…

华为HarmonyOS借助AR引擎帮助应用实现虚拟与现实交互的能力3-获取设备位姿

设备位姿描述了物体在真实世界中的位置和朝向。AR Engine提供了世界坐标下6自由度&#xff08;6DoF&#xff09;的位姿计算&#xff0c;包括物体的位置&#xff08;沿x、y、z轴方向位移&#xff09;和朝向&#xff08;绕x、y、z轴旋转&#xff09;。通过AR Engine&#xff0c;您…

【Git】Git常用命令

目录 1 前言2 git命令2.1 branch2.2 checkout2.3 pull and push2.4 config2.4.1 Proxy 2.5 tag2.6 rebase2.7 patch2.8 remote2.9 submodule2.10 rm2.10 gitignore2.11 某个commit更改了哪些文件2.12 clean 3 结束语 1 前言 本章记录总结在使用git过程中常用的一些命令&#x…

cgroup2版本下使用cgroups对内存/cpu进行控制

先查看cgroups的版本支持: cat /proc/filesystems | grep cgroup 运行结果: 如上表示支持cgroup2版本 一、对内存进行控制 cgroup版本对于内存控制是单独使用/sys/fs/cgroup/memory路径控制的,而在cgroup2版本中是统一管理,所以没有该路径,所以只需先进入该路径: cd /sys/…

安卓应用跳转回流的统一和复用

本文字数&#xff1a;6799字 预计阅读时间&#xff1a;35分钟 作为一个功能复杂的应用&#xff0c;无法避免地需要支持众多路径的回流&#xff0c;比如从Launcher、从Push通知、从端外H5、从合作第三方App以及从系统资源分享组件等。 我们知道&#xff0c;不同的回流路径会通过…