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

news2024/12/24 0:28:42

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

  • 一、menuconfig配置
  • 二、配置 CMakeLists
    • 1. 设置项目的额外组件目录
    • 2. 设置头文件搜索目录
  • 三、在 ESP32 上执行 HTTP 请求的基本步骤
    • 1. 创建 TCP 连接
    • 2. 设置 HTTP 请求
    • 3. 发送 HTTP 请求
    • 4. 接收 HTTP 响应
    • 5. 处理 HTTP 响应
    • 6. 关闭 TCP 连接
  • 三、示例
    • 1. http_request.h
    • 2. http_request.c
      • http_request_send
      • esp_http_client_config_t 结构体
      • esp_http_client_init() 函数
      • esp_http_client_perform() 函数
      • esp_http_client_cleanup() 函数

官网文档:
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 $ENV{IDF_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 客户端句柄。

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

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

相关文章

35岁以上的大龄测试员们,后来都干什么去了?

为什么软件测试行业看不见白发苍苍的软件测试员?大龄测试员都去哪里了?各个公司会辞退大龄测试员吗? 如果一位 50 多岁的测试员申请 20 多岁或 30 多岁的职位&#xff0c;有多少公司会雇用他们呢?关于这个问题&#xff0c;有很多流言传说&#xff0c;也有一些残酷的现实。…

努力优化和改造不好的环境,去设计新的、积极的、适合自己的环境

你知道环境对你的影响有多大吗&#xff1f;自己的的社交圈也是一个环境如果你待在一个只知道吃喝玩乐&#xff0c;不思进取&#xff0c;天天玩手机、打游戏的圈子里那你很大程度也会被影响&#xff0c;因为你不跟他们一起你就融入不进去&#xff0c;就会被孤立&#xff0c;很多…

优秀蓝牙耳机推荐,热销不错的四款蓝牙耳机推荐

蓝牙耳机作为目前最流行的数码产品&#xff0c;受到很多人追捧&#xff0c;蓝牙耳机摆脱了有线蓝牙耳机的束缚&#xff0c;能够更好听歌打游戏&#xff0c;随时取用&#xff0c;更为便利&#xff0c;当然&#xff0c;随着耳机的大幅度创新&#xff0c;也导致很多人在选购耳机的…

内网渗透(四十三)之横向移动篇-SMB远程执行命令横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

前端性能优化的一些技巧(90% chatGpt生成)

终于弄好了chatGpt的账号&#xff0c;赶紧来体验一波。先来一波结论&#xff0c;这篇文章的主要内容来源&#xff0c;90%是用chatGpt生成的。先上chatGpt的生成的结果&#xff1a;作为一名懒惰的程序员&#xff0c;chatGpt会帮助我变得更懒...&#xff0c;好了下面开始文章的正…

GEE学习笔记 六十八:【GEE之Python版教程二】配置Python开发环境

这一篇内容主要讲解两部分内容&#xff0c;第一部分是本地python开发环境的配置&#xff0c;第二部分是GEE的python开发环境配置。我这里做的所有的操作都是在我的Mac电脑上做的&#xff0c;Windows上操作类似&#xff0c;如果有不清楚的可以自行搜索相关操作步骤。 第一部分&…

pytorch零基础实现语义分割项目(四)——模型训练与预测

模型训练与预测项目列表前言损失函数one_hotDice LossFocal Loss模型参数与训练预测项目列表 语义分割项目&#xff08;一&#xff09;——数据概况及预处理 语义分割项目&#xff08;二&#xff09;——标签转换与数据加载 语义分割项目&#xff08;三&#xff09;——语义…

winserver服务器硬盘满了怎么清理? 服务器硬盘空间不足清理方法

本文主要介绍我在维护windows server服务器期间总结的一些磁盘清理方式。如对您有所帮助&#xff0c;不甚荣幸。 文章目录一、C盘清理1. System32的日志文件2. IIS的日志文件3. .Net Framework的缓存文件4. 清理其他不必要文件5. 虚拟内存从c盘移到其他硬盘二、其他软件清理1. …

【离散数学】4. 图论

1.数理逻辑 2. 集合论 3. 代数系统 4. 图论 图&#xff1a;点边边与点的映射函数 连通性与判别 欧拉图与哈密尔顿图 二分图和平面图与欧拉公式 树及生成树 单源点最短路径&#xff1a;Dijkstra算法 对偶图 4. 图论 4.1 图的基本概念 4.1.1 图 一个图G是一个三重组 <V(G),E…

【LeetCode】No.232. 用栈实现队列 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/implement-queue-using-stacks/ 1. 题目介绍&#xff08;232. 用栈实现队列&#xff09; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff…

两年外包生涯做完,感觉自己废了一半....

先说一下自己的情况。大专生&#xff0c;17年通过校招进入湖南某软件公司&#xff0c;干了接近2年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

慕了没?3年经验,3轮技术面+1轮HR面,拿下字节30k*16薪offer

前段时间有个朋友出去面试&#xff0c;这次他面试目标比较清晰&#xff0c;面的都是业务量大、业务比较核心的部门。前前后后去了不少公司&#xff0c;几家大厂里&#xff0c;他说给他印象最深的是字节3轮技术面1轮HR面&#xff0c;他最终拿到了30k*16薪的offer。第一轮主要考察…

MyBatis-Plus详细讲解(整合spring Boot)

哈喽&#xff0c;大家好&#xff0c;今天带大家了解的是MyBatis-Plus&#xff08;简称 MP&#xff09;&#xff0c;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。首先说一下MyBatis-Plus的愿景是什么&…

十五.程序环境和预处理

文章目录一.程序翻译环境和执行环境1.ANSI C 标准2.程序的翻译环境和执行环境二.程序编译和链接1.翻译环境2.编译本身的几个阶段3.运行环境三.预处理1.预定义符号2.#define&#xff08;1&#xff09;#define定义标识符&#xff08;2&#xff09;#define定义宏&#xff08;3&…

【Linux】——基础开发工具和vim编辑器的基本使用方法

目录 Linux 软件包管理器 yum Linux编辑器-vim使用 1.vim的基本概念 2. vim的基本操作 3. vim正常模式命令集 4. vim末行模式命令集 如何配置vim Linux 软件包管理器 yum yum是Linux下的一个下载软件的软件 对于yum&#xff0c;现阶段只需要会使用yum的三板斧就…

【linux】——gcc/g++,make/makefile的简单使用

目录 1.gcc的基本使用 2.Linux下的静态库和动态库的理解 3.Linux项目自动化构建工具——make/makefile 1.gcc的基本使用 gcc是专门用来编译c语言的 g是专门用来编译c的&#xff0c;但是g也能够用来编译c语言 预处理&#xff08;进行宏替换&#xff09; 预处理功能主要包括宏…

Idea无法识别SpringBoot配置文件

SpringBoot的配置文件 application.properties > application.yml > application.yaml 配置文件间的加载优先级 properties&#xff08;最高&#xff09;> yml > yaml&#xff08;最低&#xff09;不同配置文件中相同配置按照加载优先级相互覆盖&#xff0c;不同配…

免费使用通配符域名证书

文章目录前言一、手动安装acme.sh操作1、安装acme.sh2、使用dns api自动续签二、宝塔自动操作【推荐】总结前言 之前个人站点一般都是使用阿里云免费单域名证书&#xff0c;虽然好用但是只有一年有效&#xff0c;到期只能手动重新申请&#xff0c;并且每次弄个子域名出来就要重…

【C++】类和对象练习——日期类的实现

文章目录前言1. 日期的合法性判断2. 日期天数&#xff08;/&#xff09;2.1 和的重载2.2 对于两者复用的讨论3. 前置和后置重载4. 日期-天数&#xff08;-/-&#xff09;5. 前置- -和后置- -的重载6. 日期-日期7. 流插入<<重载8. 流提取>>重载9. 总结10. 源码展示前…

JavaScript - 函数

文章目录一、箭头函数二、函数名三、理解参数3.1 箭头函数中的参数四、没有重载五、默认参数值5.1 默认参数作用域与暂时性死区六、参数扩展与收集6.1 扩展参数6.2 收集参数七、函数声明与函数表达式八、函数作为值九、函数内部9.1 arguments9.2 this9.3 caller9.4 new.target十…