ESP-C3入门11. 创建最基本的HTTP请求

Posted 编程圈子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP-C3入门11. 创建最基本的HTTP请求相关的知识,希望对你有一定的参考价值。

ESP-C3入门11. 创建最基本的HTTP请求

官网文档:
https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-reference/protocols/esp_http_client.html

一、menuconfig配置

打开ESP-IDF 4.4 CMD命令窗口,进入项目,运行: idf.py menuconfig,打开配置窗口:

选择 Component config- ESP HTTP client菜单:

钩选:

保存设置到自己项目:

二、配置 CMakeLists

1. 设置项目的额外组件目录

# 设置项目的额外组件目录,允许使用ESP-IDF示例中的公共组件。
set(EXTRA_COMPONENT_DIRS $ENVIDF_PATH/components)

2. 设置头文件搜索目录

CMakeLists.h 中要包含 esp_http_client的头文件位置:

# 设置项目的包含目录,这些是要搜索头文件的目录
set(INCLUDE_DIRS
        $INCLUDE_DIRS
        $CMAKE_CURRENT_SOURCE_DIR
        $IDF_PATH/components/esp_http_client/include
        )
include_directories($INCLUDE_DIRS)

这样就能使用 esp_http_client了。

三、在 ESP32 上执行 HTTP 请求的基本步骤

在 ESP32 上进行 HTTP 请求需要使用 TCP/IP 套接字和 HTTP 库来实现。
ESP32 IDF的esp_http_client 库提供了一组易于使用的 API,可以自动处理 HTTP 头和响应内容。

1. 创建 TCP 连接

使用 tcpip_adapter 和 lwip 库创建一个 TCP 连接。可以使用 lwip 库提供的函数(如 tcp_new() 和 tcp_connect())来创建和连接套接字。

2. 设置 HTTP 请求

使用 HTTP 协议创建一个请求消息。请求消息包括 HTTP 方法(如 GET、POST 等)和请求的 URL,以及一些 HTTP 头部(如 Content-Type、Content-Length 等)和负载数据(如果有的话)。

3. 发送 HTTP 请求

使用 lwip 库提供的 tcp_write() 函数将请求消息发送到服务器。

4. 接收 HTTP 响应

使用 lwip 库提供的 tcp_recv() 函数从服务器接收响应消息。通常,响应消息由一个或多个 TCP 数据包组成,因此需要在接收数据时进行缓冲区处理。

5. 处理 HTTP 响应

对响应消息进行处理,例如解析响应头、解码响应正文、处理错误码等。

6. 关闭 TCP 连接

使用 lwip 库提供的 tcp_close() 函数关闭 TCP 连接。

三、示例

1. http_request.h

#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H
#include "esp_http_client.h"
#define HTTP_URL "http://www.example.com"
esp_err_t http_event_handler(esp_http_client_event_t *evt);
void request(const char* url);
#endif

2. http_request.c

#include <esp_err.h>
#include <esp_log.h>
#include "network/include/http_request.h"

static const char *TAG = "HTTP_REQUEST";
#define MAX_HTTP_OUTPUT_BUFFER 2048

// HTTP 请求的处理函数
esp_err_t http_event_handler(esp_http_client_event_t *evt)

    // 缓存http响应的buffer
    static char *output_buffer;
    // 已经读取的字节数
    static int output_len;
    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:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);

            if (!esp_http_client_is_chunked_response(evt->client)) 
                // 如果配置了user_data buffer,则把响应复制到该buffer中
                if (evt->user_data) 
                    memcpy(evt->user_data + output_len, evt->data, evt->data_len);
                 else 
                    if (output_buffer == NULL) 
                        output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));
                        output_len = 0;
                        if (output_buffer == NULL) 
                            ESP_LOGE(TAG, "Failed to allocate memory for output buffer");
                            return ESP_FAIL;
                        
                    
                    memcpy(output_buffer + output_len, evt->data, evt->data_len);
                
                output_len += evt->data_len;
            

            break;
        case HTTP_EVENT_ON_FINISH:
            ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
            if (output_buffer != NULL) 
                // Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
                // ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
                free(output_buffer);
                output_buffer = NULL;
            
            output_len = 0;
            break;
        case HTTP_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
            if (output_buffer != NULL) 
                free(output_buffer);
                output_buffer = NULL;
            
            output_len = 0;
            break;
    
    return ESP_OK;



void request(const char *url) 
    // 响应结果放在这里
    char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = 0;

    // 创建一个 HTTP 客户端配置
    esp_http_client_config_t config = 
            .method = HTTP_METHOD_GET,
            .url = url,
            .event_handler = http_event_handler,
            .user_data = local_response_buffer,
            .disable_auto_redirect = true,
    ;

    // 创建一个 HTTP 客户端并执行 GET 请求
    esp_http_client_handle_t client = esp_http_client_init(&config);
    esp_err_t err = esp_http_client_perform(client);

    // 检查请求是否成功
    if (err == ESP_OK) 
        int len =  esp_http_client_get_content_length(client);
        ESP_LOGI(TAG, "Status = %d, content_length = %d",
                 esp_http_client_get_status_code(client),//状态码
                 len);//数据长度

     else 
        printf("HTTP GET request failed: %s\\n", esp_err_to_name(err));
    
    printf("Response: %.*s\\n", strlen(local_response_buffer), local_response_buffer);

    //断开并释放资源
    esp_http_client_cleanup(client);

主要函数说明:

http_request_send

用于发送 HTTP 请求的函数 ,该函数接受一个 http_request_t 类型的指针作为参数,其中包含了 HTTP 请求的 URL、请求方法、请求头以及 POST 数据。在

esp_http_client_config_t 结构体

用于配置 HTTP 客户端的参数,包括 URL、请求方法和事件处理函数。然后,根据请求中是否包含请求头和 POST 数据来设置 HTTP 客户端的相应参数。

esp_http_client_init() 函数

用来创建一个 HTTP 客户端句柄。

esp_http_client_perform() 函数

发送 HTTP 请求。

esp_http_client_cleanup() 函数

释放 HTTP 客户端句柄。

以上是关于ESP-C3入门11. 创建最基本的HTTP请求的主要内容,如果未能解决你的问题,请参考以下文章

ESP-C3入门14. 实现基本的web server

ESP-C3入门14. 实现基本的web server

ESP-C3入门14. 实现基本的web server

ESP-C3入门12. HTTPS请求堆内存使用及JSON处理

ESP-C3入门12. HTTPS请求堆内存使用及JSON处理

ESP-C3入门9. 创建TCP Server