一.HTTP协议
1.http认识
作用:http
可以实现客户端与服务器的通信
http
请求也就是动词,用于客户端向服务器发送怎么样的请求,常见的http
请求如下:
- GET: 请求从服务器获取指定资源。GET请求应该是幂等的,意味着多次执行同一个GET请求应该得到相同的结果。通常用于读取操作。
- POST: 请求服务器接受并处理请求体中的数据,通常用于提交表单数据或上传文件。POST请求可能会导致新资源的创建。
- PUT: 请求服务器存储一个资源,并用请求体中的内容替换目标资源的所有当前内容。PUT请求应该是幂等的。
- DELETE: 请求服务器删除指定的资源。DELETE请求也应该是幂等的。
- HEAD: 类似于GET请求,但服务器只返回响应头,不返回响应体。这允许客户端获取资源的元信息,而不实际获取资源本身。
- PATCH: 请求对资源应用部分修改。与PUT不同,PATCH通常用于更新资源的一部分而不是整个资源。
- OPTIONS: 请求服务器列出可以针对资源执行的HTTP方法。这个请求方法可以用来检查服务器的功能。
- CONNECT: 用于代理服务器,要求服务器切换到透明代理模式,以便客户端可以与目标服务器建立直接的连接。
- TRACE: 用于回显服务器收到的请求,主要用于测试或诊断。
所以,通信过程是这样的:客户端利用http
协议可以向服务器发送各种http
请求,服务器收到请求后可以对不同的请求做出回应。
2.http请求报文认识
一个HTTP请求报文由以下几个主要部分构成:
- 请求行(Request Line):
- 方法(Method):定义了对资源的操作,如 GET、POST、PUT、DELETE 等。
- 请求路径(Request URI):指定了请求的资源地址。
- HTTP版本(HTTP Version):指示了使用的HTTP协议版本,如 HTTP/1.1。
- 请求头(Headers):
- 一系列的键值对,提供了关于请求、响应或其他的额外信息。常见的请求头包括:
- Host:指定了请求的服务器域名。
- User-Agent:包含了发起请求的用户代理软件信息。
- Accept:指定了客户端能够接收的内容类型。
- Content-Type:对于包含正文的请求(如 POST 请求),指示了请求正文的 MIME 类型。
- Content-Length:指示了请求正文的长度(字节)。
- 一系列的键值对,提供了关于请求、响应或其他的额外信息。常见的请求头包括:
- 空行:
- 请求头和请求正文之间必须有一个空行,用于分隔头部和正文。
- 请求正文(Request Body):
- 请求的附加数据,通常用于 POST、PUT 等方法,可以包含表单数据、JSON、XML 等。
- 不是所有请求都有正文,例如 GET 请求通常不包含正文。
一个典型的HTTP请求报文可能如下所示:
POST /form.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Content-Type: application/x-www-form-urlencoded
Content-Length: 27
field1=value1&field2=value2
在这个例子中:
- 请求方法是
POST
。 - 请求路径是
/form.html
。 - HTTP版本是
HTTP/1.1
。 - 请求头包括
Host
、User-Agent
、Content-Type
和Content-Length
。 - 空行分隔头和正文。
- 请求正文是一个简单的键值对表单数据
field1=value1&field2=value2
。
理解HTTP请求报文的构成是编写HTTP服务器和客户端的关键,因为它决定了如何解析和生成请求。
3.http响应报文
HTTP响应报文由以下几个主要部分构成:
- 状态行(Status Line):
- HTTP版本(HTTP Version):指示了使用的HTTP协议版本,如 HTTP/1.1。
- 状态码(Status Code):一个三位数,指示了请求的结果。例如,200 表示成功,404 表示未找到资源。
- 状态消息(Status Message):一个文本字符串,提供了状态码的简短描述。
- 响应头(Headers):
- 一系列的键值对,提供了关于响应、资源或其他的额外信息。常见的响应头包括:
- Content-Type:指示了响应正文的 MIME 类型。
- Content-Length:指示了响应正文的长度(字节)。
- Date:指示了响应生成的时间。
- Server:包含了服务器软件的信息。
- 一系列的键值对,提供了关于响应、资源或其他的额外信息。常见的响应头包括:
- 空行:
- 响应头和响应正文之间必须有一个空行,用于分隔头部和正文。
- 响应正文(Response Body):
- 服务器返回的资源内容,可以是HTML页面、图片、视频等。
- 不是所有响应都有正文,例如某些状态码(如 204 No Content)表示响应不应包含正文。
一个典型的HTTP响应报文可能如下所示:
复制
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 1256
Date: Wed, 23 Mar 2023 22:44:00 GMT
Server: Apache/2.4.41 (Ubuntu)
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
</head>
<body>
<h1>Welcome to the Example Page!</h1>
<p>This is an example response from the server.</p>
</body>
</html>
在这个例子中:
- HTTP版本是
HTTP/1.1
。 - 状态码是
200
,表示请求成功。 - 状态消息是
OK
。 - 响应头包括
Content-Type
、Content-Length
、Date
和Server
。 - 空行分隔头和正文。
- 响应正文是一个简单的HTML页面。
理解HTTP响应报文的构成对于编写能够正确解析和处理服务器响应的客户端代码至关重要。
4.http搭建流程
HTTP 服务器
- 创建服务器实例:
- 使用
httplib::Server
类来创建一个 HTTP 服务器实例。
- 使用
- 定义路由和处理器:
- 使用
Get
,Post
,Put
,Delete
等方法来定义不同的 HTTP 路由及其对应的处理函数。 - 处理函数是一个接受请求和响应对象作为参数的函数或 lambda 表达式。
- 使用
- 处理请求:
- 在处理函数中,你可以读取请求的参数、头部、正文等。
- 根据请求内容生成响应,设置状态码、头部和正文。
- 启动服务器:
- 使用
listen
方法来启动服务器,指定 IP 地址和端口号。
- 使用
HTTP 客户端
- 创建客户端实例:
- 使用
httplib::Client
类来创建一个 HTTP 客户端实例。
- 使用
- 发送请求:
- 使用
Get
,Post
,Put
,Delete
等方法来发送 HTTP 请求。 - 可以设置请求的 URL、头部和正文。
- 使用
- 处理响应:
- 发送请求后,你会得到一个响应对象。
- 检查响应的状态码,读取响应的头部和正文。
5.环境配置
- 下载 cpp-httplib:
- 访问 cpp-httplib 的 GitHub 仓库:https://github.com/yhirose/cpp-httplib
- 克隆或下载仓库到你的本地计算机。
- 创建 Visual Studio 项目:
- 打开 Visual Studio。
- 创建一个新的 C++ 项目(可以是空项目或桌面应用程序)。
- 添加 cpp-httplib 源文件:
- 将下载的
httplib.h
头文件复制到你的 Visual Studio 项目中。 - 可以在项目中创建一个名为
include
的文件夹,然后将httplib.h
放在这个文件夹中。
- 将下载的
- 配置项目属性:
- 在解决方案资源管理器中,右键点击你的项目,选择“属性”。
- 在“属性”窗口中,选择“C/C++” -> “常规”,然后在“附加包含目录”中添加
httplib.h
所在的目录路径。
- 编写代码:
- 在你的项目中创建一个 C++ 源文件(例如
main.cpp
)。 - 在源文件中包含
httplib.h
头文件。 - 编写使用 cpp-httplib 的服务器或客户端代码。
- 在你的项目中创建一个 C++ 源文件(例如
- 编译项目:
- 点击“生成” -> “生成解决方案”来编译你的项目。
- 运行项目:
- 编译成功后,点击“调试” -> “开始执行(不调试)”或“开始调试”来运行你的应用程序。
二.初步使用
1.第一个简单程序
#include "httplib.h" // 引入 httplib 库的头文件,这是使用库的第一步
int main() {
httplib::Server svr; // 创建一个 httplib::Server 对象,这是创建 HTTP 服务器的开始
// 使用 svr.Get() 方法来定义一个路由处理函数,用于处理 GET 请求
// 第一个参数是路由路径,这里使用 "/" 表示根路径
// 第二个参数是一个 lambda 表达式,它定义了如何处理该路径的请求
// lambda 表达式的参数是 const 引用的请求对象和一个引用的响应对象
svr.Get("/", [](const httplib::Request &, httplib::Response &res) {
// 使用 res.set_content() 方法来设置响应的内容
// 第一个参数是响应的正文内容,这里是一个简单的 HTML 字符串
// 第二个参数是内容类型,这里设置为 "text/html",表示响应是一个 HTML 页面
res.set_content("<html><body><h1>Hello, World!</h1></body></html>", "text/html");
});
// 使用 svr.listen() 方法来启动服务器
// 第一个参数是服务器的 IP 地址,这里使用 "0.0.0.0" 表示监听所有网络接口
// 第二个参数是服务器的端口号,这里使用 8080
// 当服务器启动后,它将开始监听 8080 端口,并处理发送到该端口的 HTTP 请求
svr.listen("0.0.0.0", 8080);
// 如果 listen() 方法返回,说明服务器已经停止监听,通常是因为发生了错误
// 在这个简单的例子中,我们不处理 listen() 返回的错误
// 直接返回 0 表示程序正常退出
return 0;
}
#include "goods.h"
#include "log.h"
#include "datamanger.h"
#include "result.h"
int main()
{
Datemanger tm;
vector<Goods> ret = tm.select_goods("");
for (auto& t : ret)
{
cout << t.get_goods_id() << ":" << t.get_goods_name() << endl;
}
return 0;
}