ESP32基础应用之HTTP 服务器

article/2025/9/18 9:58:51

文章目录

  • 1 HTTP服务器简介
  • 2 ApiPost测试工具
  • 3 HTTP服务器实验
    • 3.1 ApiPost之GET测试
    • 3.2 ApiPost之POST测试
    • 3.3 ApiPost值PUT测试

参考资料:

  1. esp32 http服务器编程指南

1 HTTP服务器简介

  1. HTTP服务器一般指Web服务器,是指驻留于因特网上某种类型计算机的程序,可以处理浏览器等Web客户端的请求并返回相应响应,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载。目前最主流的三个Web服务器是Apache、 Nginx 、IIS。
  2. Web服务器是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连到服务器上并请求文件时,服务器将处理该请求并将文件反馈到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。服务器使用HTTP(超文本传输协议)与客户机浏览器进行信息交流,这就是人们常把它们称为HTTP服务器的原因。

参考来源:百度百科 HTTP服务器

2 ApiPost测试工具

使用ApiPost作为测试工具,如图:
在这里插入图片描述
链接:

  1. ApiPost官方地址
  2. ApiPost使用说明

3 HTTP服务器实验

参考例程:Simple HTTPD Server Example

注意:ESP32开发板作为HTTP服务器;ApiPost作为客户端
实验流程大概为:

  1. httpd_start() :创建 HTTP 服务器的实例,根据具体的配置为其分配内存和资源,并返回该服务器实例的句柄。服务器使用了两个套接字,一个用来监听 HTTP 流量(TCP 类型),另一个用来处理控制信号(UDP 类型),它们在服务器的任务循环中轮流使用。通过向 httpd_start() 传递 httpd_config_t 结构体,可以在创建服务器实例时配置任务的优先级和堆栈的大小。TCP 流量被解析为 HTTP 请求,根据请求的 URI 来调用用户注册的处理程序,在处理程序中需要发送回 HTTP 响应数据包。
  2. httpd_register_uri_handler():通过传入 httpd_uri_t 结构体类型的对象来注册 URI 处理程序。该结构体包含如下成员:uri 名字,method 类型(比如 HTTPD_GET/HTTPD_POST/HTTPD_PUT 等等), esp_err_t *handler (httpd_req_t *req) 类型的函数指针,指向用户上下文数据的 user_ctx 指针。
  3. httpd_stop():根据传入的句柄停止服务器,并释放相关联的内存和资源。这是一个阻塞函数,首先给服务器任务发送停止信号,然后等待其终止。期间服务器任务会关闭所有已打开的连接,删除已注册的 URI 处理程序,并将所有会话的上下文数据重置为空。

3.1 ApiPost之GET测试

查看get注册参数以及处理函数代码(详细代码请参考例程)。

static const httpd_uri_t hello = {.uri       = "/hello",            //具体路径,如  http://192.168.3.173:80/hello  .method    = HTTP_GET,            //方法method .handler   = hello_get_handler,   //处理函数/* Let's pass response string in user* context to demonstrate it's usage */.user_ctx  = "Hello World!i am esp32 2021.06.25"  //给客户端的响应
};
/* An HTTP GET handler */
static esp_err_t hello_get_handler(httpd_req_t *req)
{char*  buf;size_t buf_len;//获取请求头,并打印出来/* Get header value string length and allocate memory for length + 1,* extra byte for null termination */buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;if (buf_len > 1) {buf = malloc(buf_len);/* Copy null terminated value string into buffer */if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found header => Host: %s", buf);}free(buf);}buf_len = httpd_req_get_hdr_value_len(req, "Accept-Language") + 1;if (buf_len > 1) {buf = malloc(buf_len);if (httpd_req_get_hdr_value_str(req, "Accept-Language", buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found header => Accept-Language: %s", buf);}free(buf);}buf_len = httpd_req_get_hdr_value_len(req, "User-Agent") + 1;if (buf_len > 1) {buf = malloc(buf_len);if (httpd_req_get_hdr_value_str(req, "User-Agent", buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found header => User-Agent: %s", buf);}free(buf);}buf_len = httpd_req_get_hdr_value_len(req, "Connection") + 1;if (buf_len > 1) {buf = malloc(buf_len);if (httpd_req_get_hdr_value_str(req, "Connection", buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found header => Connection: %s", buf);}free(buf);}buf_len = httpd_req_get_hdr_value_len(req, "content-type") + 1;if (buf_len > 1) {buf = malloc(buf_len);if (httpd_req_get_hdr_value_str(req, "content-type", buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found header => content-type: %s", buf);}free(buf);}//获取query并打印出来,再分类/* Read URL query string length and allocate memory for length + 1,* extra byte for null termination */buf_len = httpd_req_get_url_query_len(req) + 1;if (buf_len > 1) {buf = malloc(buf_len);if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {ESP_LOGI(TAG, "Found URL query => %s", buf);char param[32];/* Get value of expected key from query string */if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);}if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);}if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);}}free(buf);}//设置响应头/* Set some custom headers */httpd_resp_set_hdr(req, "Custom-Header-11", "Custom-Value-1");httpd_resp_set_hdr(req, "Custom-Header-22", "Custom-Value-2");/* Send response with custom headers and body set as the* string passed in user context*/const char* resp_str = (const char*) req->user_ctx;httpd_resp_send(req, resp_str, strlen(resp_str));/* After sending the HTTP response the old HTTP request* headers are lost. Check if HTTP request headers can be read now. */if (httpd_req_get_hdr_value_len(req, "Host") == 0) {ESP_LOGI(TAG, "Request headers lost");}return ESP_OK;
}

关于HTTP报文接收请参考:这里

  1. 编译并烧录程序,打开串口,记录IP地址在这里插入图片描述
  2. 打开ApiPost,发送get的uri。在这里插入图片描述
  3. 打开ESP32开发板的串口,得到数据如下 :在这里插入图片描述
  4. 打开ApiPost查看响应数据在这里插入图片描述在这里插入图片描述在这里插入图片描述
    请求头解释如下:
    Accept-Encoding: gzip, deflate, br
    表示浏览器支持的编码是gzip、deflate、br(客户端支持的编码)
    Accept-Language: zh-CN
    浏览器支持的语言分别是简体中文和中文(当前客户端可以支持的语言)
    User-Agent:ApiPOST Runtime +https://www.apipost.cn
    用户代理,客户端是ApiPOST,如果是其他浏览器则显示其他浏览器
    更多请求头解释清参考:HTTP服务器(一)

3.2 ApiPost之POST测试


static const httpd_uri_t echo = {.uri       = "/echo",            //具体路径,如  http://192.168.3.173:80/echo.method    = HTTP_POST,          //方法method .handler   = echo_post_handler,  //处理函数.user_ctx  = NULL
};/* An HTTP POST handler */
static esp_err_t echo_post_handler(httpd_req_t *req)
{char buf[100];int ret, remaining = req->content_len;while (remaining > 0) {/* Read the data for the request */if ((ret = httpd_req_recv(req, buf,MIN(remaining, sizeof(buf)))) <= 0) {if (ret == HTTPD_SOCK_ERR_TIMEOUT) {/* Retry receiving if timeout occurred */continue;}return ESP_FAIL;}/* Send back the same data */httpd_resp_send_chunk(req, buf, ret);  remaining -= ret;/* Log data received */ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");ESP_LOGI(TAG, "%.*s", ret, buf);ESP_LOGI(TAG, "====================================");}// End responsehttpd_resp_send_chunk(req, NULL, 0);return ESP_OK;
}
  1. 打开ApiPost,发送POST的uri。在这里插入图片描述
  2. 打开ESP32开发板的串口,得到数据如下 :在这里插入图片描述

3.3 ApiPost值PUT测试

/* An HTTP PUT handler. This demonstrates realtime* registration and deregistration of URI handlers*/
static esp_err_t ctrl_put_handler(httpd_req_t *req)
{char buf;int ret;if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) {if (ret == HTTPD_SOCK_ERR_TIMEOUT) {httpd_resp_send_408(req);}return ESP_FAIL;}if (buf == '0') {/* URI handlers can be unregistered using the uri string */ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");httpd_unregister_uri(req->handle, "/hello");httpd_unregister_uri(req->handle, "/echo");/* Register the custom error handler */httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);}else {ESP_LOGI(TAG, "Registering /hello and /echo URIs");httpd_register_uri_handler(req->handle, &hello);httpd_register_uri_handler(req->handle, &echo);/* Unregister custom error handler */httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);}/* Respond with empty body */httpd_resp_send(req, NULL, 0);return ESP_OK;
}static const httpd_uri_t ctrl = {.uri       = "/ctrl",.method    = HTTP_PUT,.handler   = ctrl_put_handler,.user_ctx  = NULL
};
  1. 打开ApiPost,发送PUT的uri,且Body部分写0在这里插入图片描述
  2. 打开ESP32开发板的串口,得到数据如下 :在这里插入图片描述
  3. 打开ApiPost,发送PUT的uri,且Body部分写除0其他数据在这里插入图片描述
  4. 打开ESP32开发板的串口,得到数据如下 :在这里插入图片描述

http://chatgpt.dhexx.cn/article/vBhVdWGL.shtml

相关文章

http 服务器搭建

目录 http 服务器搭建有很多条数据时用response.write测试服务器是否开启 http 服务器搭建 通过http模块提供的方法可以创建服务器 1 引入http模块 &#xff08;nodejs内置模块&#xff0c; 可以直接引入&#xff09; const http require(http);创建服务器http.createServer…

HTTP服务器(一)HTTP服务器入门介绍

一、简介 1.1、做项目的时候&#xff0c;要请求REST服务器。而FEST服务器还是用http基本原理(即阉割版)来请求。 1.2、请求端口EndPoint/请求方法Method/请求内容格式ContentType/请求的数类型PostData(一般为JSon格式)。 1.3、我们熟悉的HTTP、FTP、Telnet等协议都是建立在…

【八】http服务器开发--实现一个http服务器

文章目录 一、整体概述二、接收http请求三、响应http请求四、完整代码即效果4.1 完整代码&#xff1a;4.2 实现过程 附&#xff08;stat函数&#xff09; 一、整体概述 本节主要实现一个http服务器的示例&#xff1b;该http服务器的主要功能是&#xff0c;在浏览器端访问服务器…

蓝桥杯c语言基础试题答案,试题 基础练习 Huffuman树 蓝桥杯 C语言

资源限制 时间限制&#xff1a;1.0s 内存限制&#xff1a;512.0MB 问题描述 Huffman树在编码中有着广泛的应用。在这里&#xff0c;我们只关心Huffman树的构造过程。 给出一列数{pi}{p0, p1, …, pn-1}&#xff0c;用这列数构造Huffman树的过程如下&#xff1a; 1. 找到{pi}中最…

蓝桥杯基础试题 字母图形 C语言实现

资源限制 时间限制&#xff1a;1.0s 内存限制&#xff1a;256.0MB 问题描述 利用字母可以组成一些美丽的图形&#xff0c;下面给出了一个例子&#xff1a; ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形&#xff0c;请找出这个图形的规律&#xff0c…

蓝桥杯c语言b组试题及答案,2014蓝桥杯C语言本科B组预赛试题

2014蓝桥杯C语言本科B组预赛试题 2014 蓝桥杯 C/C语言本科 B 组预赛试题12014 蓝桥杯 C/C语言本科 B 组预赛试题(完整)1.啤酒和饮料啤酒每罐 2.3 元&#xff0c;饮料每罐 1.9 元。小明买了若干啤酒和饮料&#xff0c;一共花了 82.3 元。我们还知道他买的啤酒比饮料的数量少&am…

2018年蓝桥杯C语言B组

第一题 标题&#xff1a;第几天 2000年的1月1日&#xff0c;是那一年的第1天。 那么&#xff0c;2000年的5月4日&#xff0c;是那一年的第几天&#xff1f; 注意&#xff1a;需要提交的是一个整数&#xff0c;不要填写任何多余内容 第二题 标题&#xff1a;明码 汉字的字…

(求救大佬)蓝桥杯C语言试题 算法训练 C++ CH08 01

题目&#xff1a; 求解我的代码有什么问题&#xff0c;为什么不能通过蓝桥的编译&#xff0c;但运行结果都正确。 我的代码&#xff1a; #include<stdio.h> int main() { double ssh,zrf,y,x,g,f; int a,b,c,d,t,x1,x2,x3,x4,q; int i,j; scanf("%d%d%d%d",&a…

蓝桥杯训练题C语言

开学后就很少抽空写写题了&#xff0c;所以这次只有几道题目和大家分享一下了。 有些真题也有些VIP基础题&#xff0c;想和大家分享一下。&#xff08;有些是仿的其他博主的代码&#xff0c;&#xff0c;&#xff0c;&#xff0c;因为有些确实难&#xff08;呜呜呜~&#xff0…

蓝桥杯研究生c语言试题答案,蓝桥杯试题C语言答案.doc

蓝桥杯试题C语言答案.doc 下载提示(请认真阅读)1.请仔细阅读文档&#xff0c;确保文档完整性&#xff0c;对于不预览、不比对内容而直接下载带来的问题本站不予受理。 2.下载的文档&#xff0c;不会出现我们的网址水印。 3、该文档所得收入(下载内容预览)归上传者、原创作者&am…

蓝桥杯 C语言 试题 历届试题 格子刷油漆

试题 历届试题 格子刷油漆 问题描述   X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形&#xff08;如下图所示&#xff09;&#xff0c;现需要把这些格子刷上保护漆。 你可以从任意一个格子刷起&#xff0c;刷完一格&#xff0c;可以移动到和它相邻的格子&#xff08;…

蓝桥杯 C语言 试题 历届试题 网络寻路

试题 历届试题 网络寻路 问题描述 X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包&#xff0c;为了安全起见&#xff0c;必须恰好被转发两次到达目的地。该包可能在任意一个节点产生&#xff0c;我们需要知道该网络中一共有多少种不同的转发…

蓝桥杯 C语言 试题 算法训练 审美课

试题 算法训练 审美课 问题描述   《审美的历程》课上有n位学生&#xff0c;帅老师展示了m幅画&#xff0c;其中有些是梵高的作品&#xff0c;另外的都出自五岁小朋友之手。老师请同学们分辨哪些画的作者是梵高&#xff0c;但是老师自己并没有答案&#xff0c;因为这些画看上…

C语言课程设计——25道蓝桥杯练习题

文章目录 一、基础练习1.fib数列题目解题思路解题代码解法一(简单递推)&#xff1a;时间复杂度O(n)解法二(矩阵快速幂)&#xff1a;时间复杂度O(logn) 2.闰年判断题目解题思路解题代码 3. 数列特征题目解题思路解题代码 4.查找整数题目解题思路解题代码解法一&#xff1a;C风格…

蓝桥杯C语言程序设计真题

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、真题总结 前言 下面是蓝桥杯历年的真题希望对大家有用 一、真题 1&#xff0c;隔行变色 Excel表的格子很多&#xff0c;为了避免把某行的数据和相邻行混…

2022年第十三届蓝桥杯大赛C组真题C/C++解析(上)

**今天给大家带来2022年&#xff0c;第十三届蓝桥杯大赛的真题解析**转眼间&#xff0c;距离考试已经过去很长时间了&#xff0c;今天解元给大家解析一下&#xff0c;有问题欢迎大家指点 :笑: 下面进入正题 前言填空题1.排列字母2.特殊时间 编程题1.纸张尺寸1.1纸张大小代码 2.…

pthread+Windows环境搭建

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 为什么会要用到pthread库&#xff1f;一、pthread库下载二、使用步骤1.创建VS工程2.设置环境变量2.1动态载入2.2静态载入 三、结语 为什么会要用到pthread库&#x…

pthread_cond_timedwait函数使用

1 函数原型 #include <pthread.h>int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime); int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex); …

Pthread线程基础学习

后面会尝试使用冰搜和goole搜索来学习技术&#xff0c;互联网上知识的学习也是符合二八定律的&#xff0c;既然如此&#xff0c;我们何不去选择最好的文章呢。 文章参考&#xff1a; https://randu.org/tutorials/threads/ http://www.yolinux.com/TUTORIALS/LinuxTutorialPosi…

pthread 线程创建

1.1代码 #include <pthread.h> #include <stdio.h> #include <unistd.h>static int my_thread_func (void *data) {while(1){sleep(1);} }main() {pthread_t tid;int ret;// 1.创建接收线程ret pthread_create(&tid, NULL,my_thread_func, NULL);if(ret…