基于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. Go语言之main包

    Go语言的代码通过包(package)组织,包类似于其他语言里的库(libraries)或者模块(modules).一个包由位于单个目录下的一个或多个go源文件组成,目录定义包的作用.每个源文件都以一 ...

  2. 域名更换为itwxe.com

    域名 uukongjian.com 更换为 itwxe.com,笔名 SunnyBear 更改为 IT王小二. 一.前言 4 月 21 号域名备案通过,开始折腾新买的服务器,本来这篇文章在 5 月 1 ...

  3. 『居善地』接口测试 — 7、Requests库使用proxies代理发送请求

    目录 1.代理的了解 2.代理的分类 (1)正向代理 (2)反向代理 (3)总结 3.Requests库使用代理 4.总结 1.代理的了解 在上图中我们可以把Web server看成是Google服务 ...

  4. 深度学习编译与优化Deep Learning Compiler and Optimizer

    深度学习编译与优化Deep Learning Compiler and Optimizer

  5. 利用MONAI加速医学影像学的深度学习研究

    利用MONAI加速医学影像学的深度学习研究 Accelerating Deep Learning Research in Medical Imaging Using MONAI 医学开放式人工智能网络 ...

  6. JUC 并发编程--07 阻塞队列版本的 生产者消费者(不使用synchronized和 lock),也有一些疑惑,最终解惑

    直接上代码: 前提是你已经 熟悉了原子类,volatile,和阻塞队列 public class JucPCdemo03 { /** * 阻塞队列的应用: 这里实现的生产者消费者,生产一个消费一个 * ...

  7. Java SSM框架理论知识

    一.Spring理论知识 1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心:1.IOC/DI(控制反转/依赖注入 ...

  8. NX二次开发-通过数组创建矩阵

    函数:UF_CSYS_create_matrix() 函数说明:通过数组创建矩阵. 用法: #include <uf.h> #include <uf_csys.h> exter ...

  9. org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element

    org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element(识别不到想要的元素) 想获取 ...

  10. 项目启动报错:Redis health check failed

    最近是重新开发整个项目,在上线测试的时候发现这个问题. 项目环境:SpringBoot2.x+Consul+Redission+Maven 报错的信息如下: o.s.b.a.redis.RedisHe ...