基于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笔记的更多相关文章

  1. SQL Server笔记

    SQL Server所能读取的最小单位是页,每个页8KB,8个物理上连续的页就是一个区,这样数据库中每MB就包含有16个区 堆是没有聚集索引的表.如果表格上没有聚集索引,数据行将不按任何特殊顺序存储, ...

  2. SQL Server 笔记

    第一章数据库的基本操作: >创建数据库: create database my_db(逻辑名称) on primary ( name='my_db.mdf',(物理名称) filename='F ...

  3. linux配置server笔记

    设置防火墙开放80port -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT 尽管看不懂是什么,可是这个是用于开放80p ...

  4. CentOS 64位下安装Postfix+Dovecot 配置邮件server笔记

    Postfix 和Dovecot功能确实非常强大,支持各种认证方式, 配置非常灵活, 就由于太过于灵活, 反而安装配置的过程中,easy有各种各样的陷阱,碰到问题了. 日志是最好的解决的方法了.    ...

  5. SQL Server笔记-语法

    1.USE <DatabaseName> //选择数据库 例:USE [master] //master是系统默认数据库 2.字段或表名与保留字或关键字重名时需要加. 3.COMPATIB ...

  6. SQL Server笔记——sql语句创建数据库

    MS SQLServer的每个数据库包含: 1个主数据文件(.mdf)必须. 1个事务日志文件(.ldf)必须. 可以包含: 任意多个次要数据文件(.ndf) 多个事务日志文件 CREATE DATA ...

  7. sql server 笔记(数据类型/新建、修改、删除数据表/)

    1.数据类型: Character 字符串 / Unicode 字符串 / Binary 类型 / Number 类型  /  Date 类型  / 其他数据类型 详解:http://www.w3sc ...

  8. Windows Server 笔记(七):Windows Server 2012 R2 NIC Teaming(NIC组)

    什么是NIC Teaming?         NIC Teaming 就是将两个或更多的网络适配器组合在一起,从而达到容错和带宽聚合作用.NIC Teaming 中的每个网络适配器都是物理存在的(虚 ...

  9. sql server 笔记1--case、WAITFOR、TRY CATCH

    一.case 转自:http://blog.csdn.net/add8849/article/details/576424 深入使用:http://blog.csdn.net/akuoma/artic ...

  10. 使用nginx+nginx-rtmp-module+ffmpeg搭建流媒体server笔记(十)

    第十部分 -- 开发板測试 前几天已经分别将nginx和ffmpeg移植到了开发板上面.可是还是没有进行不论什么的測试并不知道移植后的效果怎样. 今天分别做了两个測试.证明移植的结果是可用的. 1.測 ...

随机推荐

  1. rabbit_消费者

    import pika import json import time import os import ast import uuid import time import json import ...

  2. Proteus中包含的传感器类型(Transducers)

    1. 传感器列表 2. 部分传感器的测量电路 (1)光照传感器,搭采样电阻,测电压输出. (2)距离传感器,带采样电阻,测电压输出. (3)粉尘传感器,测PWM脉宽 其余传感器多为总线类型的传感器,各 ...

  3. TVM编译机器学习到 WASM 和 WebGPU

    TVM编译机器学习到 WASM 和 WebGPU TLDR TVM 深度学习编译器对 WASM 和 WebGPU 的支持.实验表明,TVM 的 WebGPU 后端在将模型部署到 Web 时可以接近原生 ...

  4. Paddle Inference原生推理库

    Paddle Inference原生推理库 深度学习一般分为训练和推理两个部分,训练是神经网络"学习"的过程,主要关注如何搜索和求解模型参数,发现训练数据中的规律,生成模型.有了训 ...

  5. 3D点云重建原理及Pytorch实现

    3D点云重建原理及Pytorch实现 Pytorch: Learning Efficient Point Cloud Generation for Dense 3D Object Reconstruc ...

  6. 车联网V-2X智能汽车驾驶

    车联网V-2X智能汽车驾驶 早期的功能互联汽车无法满足全球车主针对不同应用和定制移动服务的各种需求.这导致较低的客户续订率,较高的建造和运营成本以及较低的组装率.通常,在没有统一平台的情况下,不同的车 ...

  7. Fine-Tuning微调原理

    Fine-Tuning微调原理 如何在只有60000张图片的Fashion-MNIST训练数据集中训练模型.ImageNet,这是学术界使用最广泛的大型图像数据集,它拥有1000多万幅图像和1000多 ...

  8. python_request 使用jsonpath取值结果,进行接口关联

    一.jsonpath的安装 pip   install  jsonpath 二.使用举例 import jsonpath d1={"token":"hjshdsjhdsj ...

  9. Postman 的基本功能按钮解释、发送post请求及get请求、查看响应信息

    一.界面功能按钮: 二.postman模拟发送post请求: 三.postman模拟get请求: 选择请求类型-->输入请求URL-->点击send发送 四.查看响应信息

  10. Redis系列(一):安装

    本系列介绍Redis,从安装到使用,太简单的使用不介绍了,介绍一些比较有意思的功能,也会介绍一些原理性的东西.本篇先介绍Redis的单实例安装.Redis还可以做到高可用,通过哨兵和集群可以做到高可用 ...