ESP32网络入门-HTTP协议(客户端)
说明:
- 本文档由DuRuofu撰写,由DuRuofu负责解释及执行。
- 本文档介绍ESP32HTTP客户端程序
修订历史:
文档名称 | 版本 | 作者 | 时间 | 备注 |
---|---|---|---|---|
ESP32网络入门-HTTP协议(客户端) | v1.0.0 | DuRuofu | 2024-03-24 | 首次建立 |
ESP32网络入门-HTTP协议
一、概述
1.1 HTTP协议介绍
HTTP
协议(超文本传输协议HyperText Transfer Protocol),它是基于TCP协议的应用层传输协议,简单来说就是客户端和服务端进行数据传输的一种规则。
特点:
- 支持客户/服务器模式
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径,请求方法常用GET,HEAD,POST。每种方法规定了客户与服务器联系的类型不同,由于HTTP协议简单,是的HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象,正在传输的类型有Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求,服务器处理完客户的请求,并受到客户的应答后,即断开连接,采用这种方式可以节省传输时间。
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可以导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
1.2 HTTP内容
关于HTTP内容比较简单,这里建议直接阅读计算机网络有关部分,在此不再赘述。
HTTP协议使用客户端/服务器模型。客户端向服务器发送HTTP请求,服务器接收到请求后,根据请求的内容进行一定的处理,并将处理结果封装在HTTP响应中返回给客户端。HTTP请求和响应都有一定的结构,通常包含三部分:起始行、首部和主体。
可以参考:
我们在本节只需要知道发送HTTP请求的格式和接收的格式即可:
发送格式:
HTTP的起始行包含了请求方法或响应状态码等信息,如GET、POST等请求方法,200 OK、404 Not Found等响应状态码。HTTP的首部包含了请求或响应的各项属性,如Accept、Content-Type、Set-Cookie等。HTTP的主体则包含了请求或响应的具体内容,如HTML、JSON等文本数据或二进制数据。
接收格式:
URL格式:
URL(Uniform Resource Locator)是用于定位互联网上资源的地址,常见的资源包括网页、图片、视频等。URL由多个部分组成,包括协议、主机名、端口号、路径和查询字符串等。
一个标准的URL格式如下:
复制代码
1 |
|
其中,协议表示访问资源所采用的协议,如HTTP、HTTPS、FTP等;主机名表示资源所在的主机名或IP地址;端口号表示与主机通信的端口号,默认情况下使用协议默认的端口;路径表示请求的资源路径,可以是一个具体的文件路径,也可以是一个文件夹路径;查询字符串表示请求参数,以问号(?)开头,多个参数之间用&符号分隔。
例如,以下是一个标准的URL格式:
复制代码
1 |
|
其中,协议为HTTPS,主机名为www.example.com,端口号为80(默认端口号可省略),路径为/index.html,查询字符串为id=123&name=test。
请确保明白上面的内容,再开始学习ESP32的HTTP协议使用。
二、使用
下面我们使用ESP32充当浏览器,向HTTP服务器发送Request请求。
2.1 整体介绍
esp_http_client
提供了一组 API,用于从 ESP-IDF 应用程序中发起 HTTP/S 请求,具体的使用步骤如下:
首先调用
esp_http_client_init()
,创建一个esp_http_client_handle_t
实例,即基于给定的esp_http_client_config_t
配置创建 HTTP 客户端句柄。此函数必须第一个被调用。若用户未明确定义参数的配置值,则使用默认值。其次调用
esp_http_client_perform()
,执行esp_http_client
的所有操作,包括打开连接、交换数据、关闭连接(如需要),同时在当前任务完成前阻塞该任务。所有相关的事件(在esp_http_client_config_t
中指定)将通过事件处理程序被调用。最后调用
esp_http_client_cleanup()
来关闭连接(如有),并释放所有分配给 HTTP 客户端实例的内存。此函数必须在操作完成后最后一个被调用。
2.2 详细步骤
首先我们要初始化WIFI,连接WIFI,这是编写HTTP程序的基础,连接WIFI在此不再赘述。
后面的部分,默认已经连接好网络.
2.2.1 创建esp_http_client
实例
这里要使用esp_http_client_init()
创建HTTP客户端句柄实例,这个函数是 ESP32/ESP-IDF 中用于初始化 HTTP 客户端会话的函数。它接受一个指向 esp_http_client_config_t
结构的指针作为参数,该结构包含了 HTTP 客户端的配置信息。函数返回一个 esp_http_client_handle_t 类型的句柄,需要将这个句柄作为其他接口函数的输入参数来使用。在调用这个函数之后,必须在操作完成后调用 esp_http_client_cleanup 函数来清理资源。
关于esp_http_client_config_t
结构的参数如下:
成员 | 描述 |
---|---|
url | HTTP URL,如果设置了该字段,则会覆盖其他字段 |
host | 域名或 IP 地址,以字符串表示 |
port | 连接的端口,默认取决于 esp_http_client_transport_t (80 或 443) |
username | HTTP 身份验证的用户名 |
password | HTTP 身份验证的密码 |
auth_type | HTTP 身份验证类型,参见 esp_http_client_auth_type_t |
path | HTTP 路径,默认为 / 如果未设置 |
query | HTTP 查询参数 |
cert_pem | SSL 服务器证书,PEM 格式的字符串,如果客户端需要验证服务器 |
cert_len | cert_pem 缓冲区的长度。对于以 null 结尾的 PEM,可能为 0 |
client_cert_pem | SSL 客户端证书,PEM 格式的字符串,如果服务器需要验证客户端 |
client_cert_len | client_cert_pem 缓冲区的长度。对于以 null 结尾的 PEM,可能为 0 |
client_key_pem | SSL 客户端私钥,PEM 格式的字符串,如果服务器需要验证客户端 |
client_key_len | client_key_pem 缓冲区的长度。对于以 null 结尾的 PEM,可能为 0 |
client_key_password | 客户端密钥解密密码字符串 |
client_key_password_len | client_key_password 字符串的长度 |
tls_version | 连接的 TLS 协议版本,例如 TLS 1.2、TLS 1.3(默认 - 无偏好) |
user_agent | 发送 HTTP 请求时的用户代理字符串 |
method | HTTP 方法 |
timeout_ms | 网络超时时间(毫秒) |
disable_auto_redirect | 禁用 HTTP 自动重定向 |
max_redirection_count | 在接收到 HTTP 重定向状态码时的最大重定向次数,如果为零,则使用默认值 |
max_authorization_retries | 在接收到 HTTP 未经授权状态码时的最大连接重试次数,如果为零,则使用默认值。如果为 -1,则禁用授权重试 |
event_handler | HTTP 事件处理器 |
transport_type | HTTP 传输类型,参见 esp_http_client_transport_t |
buffer_size | HTTP 接收缓冲区大小 |
buffer_size_tx | HTTP 发送缓冲区大小 |
user_data | HTTP 用户数据上下文 |
is_async | 设置异步模式,目前仅支持 HTTPS |
use_global_ca_store | 使用全局 CA 存储 |
skip_cert_common_name_check | 跳过对服务器证书 CN 字段的验证 |
common_name | 指向包含服务器证书公共名称的字符串的指针。如果非 NULL,则服务器证书 CN 必须匹配此名称;如果为 NULL,则服务器证书 CN 必须匹配主机名 |
crt_bundle_attach | 指向 esp_crt_bundle_attach 函数的函数指针。启用证书包以进行服务器验证,必须在 menuconfig 中启用 |
keep_alive_enable | 启用 keep-alive 超时 |
keep_alive_idle | keep-alive 空闲时间,默认为 5 秒 |
keep_alive_interval | keep-alive 间隔时间,默认为 5 秒 |
keep_alive_count | keep-alive 数据包重试发送计数,默认为 3 次 |
if_name | 数据通过的接口名称。如果不设置,则使用默认接口 |
示例代码:
1 |
|
解释:
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER + 1] = {0};
:这一行定义了一个字符数组local_response_buffer
,用来存储 HTTP 响应内容。MAX_HTTP_OUTPUT_BUFFER
是预先定义的常量,表示了 buffer 的最大大小。esp_http_client_config_t config = { ... };
:这里创建了一个esp_http_client_config_t
结构体变量config
,并使用大括号内的初始化列表对其进行初始化。初始化列表中的字段包括:host
:设置为宏CONFIG_EXAMPLE_HTTP_ENDPOINT
,表示 HTTP 请求的目标主机。path
:设置为"/get"
,表示 HTTP 请求的路径。query
:设置为"esp"
,表示 HTTP 请求的查询参数。event_handler
:设置为_http_event_handler
,这是一个处理 HTTP 事件的回调函数。user_data
:设置为local_response_buffer
的地址,以便在 HTTP 请求完成后将响应内容存储到local_response_buffer
中。disable_auto_redirect
:设置为true
,禁用 HTTP 的自动重定向功能。
esp_http_client_handle_t client = esp_http_client_init(&config);
:这一行调用了esp_http_client_init
函数来初始化一个 HTTP 客户端,并将上述配置传递给该函数。函数返回一个esp_http_client_handle_t
类型的客户端句柄,以供后续的 HTTP 请求使用。
2.2.2 执行HTTP客户端的各种操作
具体使用就很简单了:
GET请求
esp_http_client_perform():esp_http_client需要使用init函数创建的参数。此函数执行esp_http_client的所有操作,从打开连接,发送数据,下载数据和关闭连接(如有必要)。所有相关事件都将在event_handle(由定义esp_http_client_config_t)中调用。此功能执行其工作并阻止当前任务,直到完成
1 |
|
上面这段代码执行了一个HTTP GET请求,并根据执行结果打印相应的日志信息。
POST请求
1 |
|
2.2.3 关闭链接,并释放系统资源
1 |
|
完成esp_http_client的任务后,这是最后一个要调用的函数。它将关闭连接(如果有)并释放分配给HTTP客户端的所有内存
三、案例
使用HTTP get请求获取我的博客首页
1 |
|
效果:
成功获取到了博客网站的内容:
内容一致: