ESP32-http server笔记
基于ESP-IDF4.1
- #include <esp_wifi.h>
- #include <esp_event.h>
- #include <esp_log.h>
- #include <esp_system.h>
- #include <nvs_flash.h>
- #include <sys/param.h>
- #include "nvs_flash.h"
- #include "esp_netif.h"
- #include "esp_eth.h"
- #include "protocol_examples_common.h"
- #include <esp_http_server.h>
- /*
- * 演示服务端创建get和post处理服务
- */
- static const char *TAG = "example";
- /* HTTP GET 处理程序 */
- static esp_err_t hello_get_handler(httpd_req_t *req)
- {
- char* buf;
- size_t buf_len;
- //获取消息头值得长度并且分配内存,而外1个字节存储null终止符
- buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
- if (buf_len > 1) {
- buf = malloc(buf_len);
- /* 将null结尾的字符串值复制到缓冲区 */
- 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, "Test-Header-2") + 1;
- if (buf_len > 1) {
- buf = malloc(buf_len);
- if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
- ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
- }
- free(buf);
- }
- buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
- if (buf_len > 1) {
- buf = malloc(buf_len);
- if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
- ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
- }
- free(buf);
- }
- // 读取URL查询字符串长度并分配内存空间
- 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];
- // 从查询字符串获取键值
- 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);
- }
- /* 设置自定义消息头 */
- httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
- httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
- //用户上下文通过字符串响应自定义消息头和消息体
- const char* resp_str = (const char*) req->user_ctx;
- httpd_resp_send(req, resp_str, strlen(resp_str));
- //检查http请求消息头是否可以被读取
- if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
- ESP_LOGI(TAG, "Request headers lost");
- }
- return ESP_OK;
- }
- static const httpd_uri_t hello = {
- .uri = "/hello",
- .method = HTTP_GET,
- .handler = hello_get_handler,
- .user_ctx = "Hello World!"
- };
- /* HTTP POST处理 */
- 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 response
- httpd_resp_send_chunk(req, NULL, 0);
- return ESP_OK;
- }
- static const httpd_uri_t echo = {
- .uri = "/echo",
- .method = HTTP_POST,
- .handler = echo_post_handler,
- .user_ctx = NULL
- };
- /*
- * 自定义错误处理
- */
- esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
- {
- if (strcmp("/hello", req->uri) == 0) {
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
- /* Return ESP_OK to keep underlying socket open */
- return ESP_OK;
- } else if (strcmp("/echo", req->uri) == 0) {
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
- /* Return ESP_FAIL to close underlying socket */
- return ESP_FAIL;
- }
- /* For any other URI send 404 and close socket */
- httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
- return ESP_FAIL;
- }
- /*
- * HTTP POST处理程序
- */
- 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
- };
- //启动web服务
- static httpd_handle_t start_webserver(void)
- {
- httpd_handle_t server = NULL;
- httpd_config_t config = HTTPD_DEFAULT_CONFIG();
- // 启动httpd服务
- ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
- if (httpd_start(&server, &config) == ESP_OK) {
- // 设置URI处理程序
- ESP_LOGI(TAG, "Registering URI handlers");
- httpd_register_uri_handler(server, &hello);
- httpd_register_uri_handler(server, &echo);
- httpd_register_uri_handler(server, &ctrl);
- return server;
- }
- ESP_LOGI(TAG, "Error starting server!");
- return NULL;
- }
- //停止web服务
- static void stop_webserver(httpd_handle_t server)
- {
- // 停止httpd服务
- httpd_stop(server);
- }
- //断网处理程序
- static void disconnect_handler(void* arg, esp_event_base_t event_base,
- int32_t event_id, void* event_data)
- {
- httpd_handle_t* server = (httpd_handle_t*) arg;
- if (*server) {
- ESP_LOGI(TAG, "Stopping webserver");
- stop_webserver(*server);
- *server = NULL;
- }
- }
- //联网处理程序
- static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
- {
- httpd_handle_t* server = (httpd_handle_t*) arg;
- if (*server == NULL) {
- ESP_LOGI(TAG, "Starting webserver");
- *server = start_webserver();
- }
- }
- //入口
- void app_main(void)
- {
- static httpd_handle_t server = NULL;
- ESP_ERROR_CHECK(nvs_flash_init());
- ESP_ERROR_CHECK(esp_netif_init());
- ESP_ERROR_CHECK(esp_event_loop_create_default());
- ESP_ERROR_CHECK(example_connect());
- /*
- * 注册事件处理服务,当断开网络时停止服务,当连接网络时重启
- */
- #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
- //连接wifi
- ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
- ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
- #endif
- #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
- //连接以太网
- ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
- ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
- #endif
- //启动服务
- server = start_webserver();
- }
需要包含的文件:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/common_components/protocol_examples_common
原文:https://gitee.com/EspressifSystems/esp-idf
ESP32-http server笔记的更多相关文章
- SQL Server笔记
SQL Server所能读取的最小单位是页,每个页8KB,8个物理上连续的页就是一个区,这样数据库中每MB就包含有16个区 堆是没有聚集索引的表.如果表格上没有聚集索引,数据行将不按任何特殊顺序存储, ...
- SQL Server 笔记
第一章数据库的基本操作: >创建数据库: create database my_db(逻辑名称) on primary ( name='my_db.mdf',(物理名称) filename='F ...
- linux配置server笔记
设置防火墙开放80port -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT 尽管看不懂是什么,可是这个是用于开放80p ...
- CentOS 64位下安装Postfix+Dovecot 配置邮件server笔记
Postfix 和Dovecot功能确实非常强大,支持各种认证方式, 配置非常灵活, 就由于太过于灵活, 反而安装配置的过程中,easy有各种各样的陷阱,碰到问题了. 日志是最好的解决的方法了. ...
- SQL Server笔记-语法
1.USE <DatabaseName> //选择数据库 例:USE [master] //master是系统默认数据库 2.字段或表名与保留字或关键字重名时需要加. 3.COMPATIB ...
- SQL Server笔记——sql语句创建数据库
MS SQLServer的每个数据库包含: 1个主数据文件(.mdf)必须. 1个事务日志文件(.ldf)必须. 可以包含: 任意多个次要数据文件(.ndf) 多个事务日志文件 CREATE DATA ...
- sql server 笔记(数据类型/新建、修改、删除数据表/)
1.数据类型: Character 字符串 / Unicode 字符串 / Binary 类型 / Number 类型 / Date 类型 / 其他数据类型 详解:http://www.w3sc ...
- Windows Server 笔记(七):Windows Server 2012 R2 NIC Teaming(NIC组)
什么是NIC Teaming? NIC Teaming 就是将两个或更多的网络适配器组合在一起,从而达到容错和带宽聚合作用.NIC Teaming 中的每个网络适配器都是物理存在的(虚 ...
- sql server 笔记1--case、WAITFOR、TRY CATCH
一.case 转自:http://blog.csdn.net/add8849/article/details/576424 深入使用:http://blog.csdn.net/akuoma/artic ...
- 使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体server笔记(十)
第十部分 -- 开发板測试 前几天已经分别将nginx和ffmpeg移植到了开发板上面.可是还是没有进行不论什么的測试并不知道移植后的效果怎样. 今天分别做了两个測试.证明移植的结果是可用的. 1.測 ...
随机推荐
- Spring的基础配置,以及注解
常用依赖 <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webm ...
- TensorFlow用法
TensorFlow用法 什么是TensorFlow TensorFlow是一个开源软件库,用于使用数据流图进行数值计算.图中的节点表示数学运算,而图的边缘表示流动的多维数据数组(张量).这种灵活的体 ...
- H.265视频编码与技术全析(下)
H.265视频编码与技术全析(下) 四.帧内预测模式 共35个(h264有9个),包括Planar,DC,33个方向模式: 除了Intra_Angular预测外,HEVC还和H.264/MPEG-4 ...
- AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)
AlexeyAB DarkNet YOLOv3框架解析与应用实践(五) RNNs in Darknet 递归神经网络是表示随时间变化的数据的强大模型.为了更好地介绍RNNs,我强烈推荐Andrej K ...
- Tensor基础实践
Tensor基础实践 飞桨(PaddlePaddle,以下简称Paddle)和其他深度学习框架一样,使用Tensor来表示数据,在神经网络中传递的数据均为Tensor. Tensor可以将其理解为多维 ...
- 英特尔Intel® Arria® 10 FPGA加速器设计
英特尔Intel Arria 10 FPGA加速器设计 Introducing the Intel Vision Accelerator Design with Intel Arria 10 FPGA ...
- MEMS传感器作为变革的驱动力
MEMS sensors as drivers for change 物联网(IoT)正在改变与周围世界互动的方式.每个人,每件事,都是相互联系的,很快就会相互联系.微机电系统(MEMS)设备和传感器 ...
- 容斥+dp (一)
ARC115 E AtCoder Problem Statement Given is a sequence of \(N\) integers \(A_1\),\(A_2\),...,\(A_N\) ...
- mybatis——解决属性名和数据库字段名不一致问题
首先说一下,我的数据库名字叫mybatis,里边有一张user表,表中有三个字段,id.name.pwd:然后实体类中对应三个属性id.name.password(id和name跟数据库字段名一致,但 ...
- RabbitMQ由浅入深入门全总结(一)
写在最前面 距离上一次发文章已经很久了,其实这段时间一直也没有停笔,只不过在忙着找工作还有学校结课的事情,重新弄了一下博客,后面也会陆陆续续会把文章最近更新出来~ 这篇文章有点长,就分了两篇Q PS: ...