http是嵌入式物联网开发常用协议,本次介绍一下esp32上怎么使用这这个协议与服务器进行通信。
一、简介
超文本传输协议(Hypertext Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出。
二、代码实现
(一) http方式接受
http的报文为请求报文格式: 请求行 - 通用信息头 - 请求头 - 实体头 - 报文主体。 请求头里面规定请求的具体方式和参数。http协议具体参考以下文章:
https://zhuanlan.zhihu.com/p/281910644?utm_id=0
https://blog.csdn.net/qq15035899256/article/details/126103840
esp32支持以下method
typedef enum {
HTTP_METHOD_GET = 0, /*!< HTTP GET Method */
HTTP_METHOD_POST, /*!< HTTP POST Method */
HTTP_METHOD_PUT, /*!< HTTP PUT Method */
HTTP_METHOD_PATCH, /*!< HTTP PATCH Method */
HTTP_METHOD_DELETE, /*!< HTTP DELETE Method */
HTTP_METHOD_HEAD, /*!< HTTP HEAD Method */
HTTP_METHOD_NOTIFY, /*!< HTTP NOTIFY Method */
HTTP_METHOD_SUBSCRIBE, /*!< HTTP SUBSCRIBE Method */
HTTP_METHOD_UNSUBSCRIBE,/*!< HTTP UNSUBSCRIBE Method */
HTTP_METHOD_OPTIONS, /*!< HTTP OPTIONS Method */
HTTP_METHOD_COPY, /*!< HTTP COPY Method */
HTTP_METHOD_MOVE, /*!< HTTP MOVE Method */
HTTP_METHOD_LOCK, /*!< HTTP LOCK Method */
HTTP_METHOD_UNLOCK, /*!< HTTP UNLOCK Method */
HTTP_METHOD_PROPFIND, /*!< HTTP PROPFIND Method */
HTTP_METHOD_PROPPATCH, /*!< HTTP PROPPATCH Method */
HTTP_METHOD_MKCOL, /*!< HTTP MKCOL Method */
HTTP_METHOD_MAX,
} esp_http_client_method_t;
方法 | 说明 | 适用版本号 |
---|---|---|
GET | 获取资源 | HTTP 1.0、HTTP 1.1 |
POST | 传输实体主体 | HTTP 1.0、HTTP 1.1 |
PUT | 传输文件 | HTTP 1.0、HTTP 1.1 |
HEAD | 获得报文首部 | HTTP 1.0、HTTP 1.1 |
DELETE | 删除文件 | HTTP 1.0、HTTP 1.1 |
OPTIONS | 访问支持的方法 | HTTP 1.1 |
(二) 回调函数实现
所有http的方式的回调函数相同,这里才有传入UserData_t* userData 结构体的方式,接收服务器返回的内容
#include <string.h>
#include <stdlib.h>
#include "esp_log.h"
#include "esp_err.h"
#include "esp_http_client.h"
typedef struct UserData_t{
char *data;
int len;
}UserData_t;
static esp_err_t http_handler(esp_http_client_event_t *evt)
{
switch(evt->event_id) {
case HTTP_EVENT_ERROR:
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED:
ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT:
ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER:
ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value);
break;
case HTTP_EVENT_ON_DATA:
if(evt->user_data){
UserData_t* userData = (UserData_t*)evt->user_data;
memcpy(userData->data+userData->len, evt->data, evt->data_len);
userData->len += evt->data_len;
}
break;
case HTTP_EVENT_ON_FINISH:
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
break;
default:
break;
}
return ESP_OK;
}
(三)GET方法的实现
- 首行里面的第一个部分就是 GET ,
- body 一般是空的,
char url[256]="http://www.baidu.com/";
char replyData[256]={0},
int replyLen=0;
```c
int http_get()
{
esp_err_t err=ESP_OK;
//服务器回复内容设置
UserData_t userData = {
.data = replyData,
.len = 0,
};
//url和链接时间等基础参数设置
esp_http_client_config_t config = {
.url = url,
.keep_alive_enable = 0,
.timeout_ms = 1000,
.event_handler = http_handler,//注册回调函数
.user_data = (void*)&userData
};
esp_http_client_handle_t client=esp_http_client_init(&config);
esp_http_client_set_method(client, HTTP_METHOD_GET);//设置方式
err = esp_http_client_perform(client);
if(err == ESP_OK){
int statusCode = esp_http_client_get_status_code(client);
ESP_LOGI(TAG, "Https post status = %d\n", statusCode);
ESP_LOGI(TAG, "sever data = %s sever data len=%d\n", userData.replyData,userData.len );//打印服务器回复内容
}
esp_http_client_cleanup(client);//请求后主动关闭链接,节约服务器资源
return err;
}
(四)Post方法的实现
- POST 请求的 body 一般不为空(body 的具体数据格式,由 header 中的 Content-Type 来描述; body 的具体数据长度,由 header 中的 Content-Length 来描述)
char url[256]="http://www.baidu.com/";
char replyData[256]={0},
int replyLen=0;
char body[256]="hello http";
```c
int http_post()
{
esp_err_t err=ESP_OK;
//服务器回复内容设置
UserData_t userData = {
.data = replyData,
.len = 0,
};
//url和链接时间等基础参数设置
esp_http_client_config_t config = {
.url = url,
.keep_alive_enable = 0,
.timeout_ms = 1000,
.event_handler = http_handler,//注册回调函数
.user_data = (void*)&userData//传参
};
esp_http_client_handle_t client=esp_http_client_init(&config);
esp_http_client_set_method(client, HTTP_METHOD_POST);//设置方式
esp_http_client_set_header(client, "Content-Type", "application/x-www-form-urlencoded");//设置传输文件格式
esp_http_client_set_post_field(client, body, strlen(body));//设置报文主体
err = esp_http_client_perform(client);
if(err == ESP_OK){
int statusCode = esp_http_client_get_status_code(client);
ESP_LOGI(TAG, "Https post status = %d\n", statusCode);
ESP_LOGI(TAG, "sever data = %s sever data len=%d\n", userData.replyData,userData.len );//打印服务器回复内容
}
esp_http_client_cleanup(client);//请求后主动关闭链接,节约服务器资源
return err;
}
三、 https配置
esp32也支持https的加密协议,提供证书加密和忽略认证(官方描述)两种形式:
- 使能第一二个配置时,当url为https链接时,使用本地内嵌的证书进行加密认证。(内嵌证书方式不做展开)
- 使能第三个配置时,会增加第四个选择,全部使能后,当url为https链接时,可以跳过服务器的证书加密认证。(推荐这种方式)
四 、总结
本次分享到此结束,专题四为esp32的协议部分使用讲解,稍后也会讲解tcp和mqtt的使用,觉得有用的读者,帮忙点个赞呗!!!!
参考
https://blog.csdn.net/qq15035899256/article/details/126103840
https://baike.baidu.com/item/HTTP/243074?fr=ge_ala
https://zhuanlan.zhihu.com/p/281910644?utm_id=0
https://docs.espressif.com/projects/esp-idf/zh_CN/release-v4.4/esp32s3/