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.測 ...
随机推荐
- 『居善地』接口测试 — 7、Requests库使用proxies代理发送请求
目录 1.代理的了解 2.代理的分类 (1)正向代理 (2)反向代理 (3)总结 3.Requests库使用代理 4.总结 1.代理的了解 在上图中我们可以把Web server看成是Google服务 ...
- NGINX缓存使用官方指南
我们都知道,应用程序和网站一样,其性能关乎生存.但如何使你的应用程序或者网站性能更好,并没有一个明确的答案.代码质量和架构是其中的一个原因,但是在很多例子中我们看到,你可以通过关注一些十分基础的应用内 ...
- Python+Selenium学习笔记14 - python官网的tutorial - just() fill() format()
repr(x).rjust(n) 左侧空格填充,右侧列对齐,str()和repr()是一种输出,也可不用,直接x.rjust() repr(x).ljust(n) 右侧空格填充,左侧列对齐 rep ...
- YOLOv4全文阅读(全文中文翻译)
YOLOv4全文阅读(全文中文翻译) YOLOv4: Optimal Speed and Accuracy of Object Detection 论文链接: https://arxiv.org/pd ...
- QT Dialog模态与非模态
模态 // 创建对话框窗口 TestDialog* dlg = new TestDialog(this); // 阻塞程序的运行 dlg->exec(); 这样的话,当运行对话窗口的时候,会阻塞 ...
- 十一、设置Nginx开机自启动
一.创建nginx.service文件 [root@svr7 ~]# vim /lib/systemd/system/nginx.service [Unit]Description=nginx ser ...
- NOIP模拟测试19「count·dinner·chess」
反思: 我考得最炸的一次 怎么说呢?简单的两个题0分,稍难(我还不敢说难,肯定又有人喷我)42分 前10分钟看T1,不会,觉得不可做,完全不可做,把它跳了 最后10分钟看T1,发现一个有点用的性质,仍 ...
- Winform中只运行运行一个实例的方法
在Program类的main方法按如下代码编写即可 1 static void Main() 2 { 3 if (Process.GetProcessesByName(Process.GetCurre ...
- DOS命令行(5)——Windows系统的配置与管理(下)
whoami --查看当前有效用户 这个工具可以用来获取本地系统上当前用户(访问令牌)的用户名和组信息,以及相应的安全标识符(SID).声明.本地系统上当前用户的权限.登录标识符(登录 ID).例如, ...
- OO unit2 summary
Unit2 一.第一次作业 1.UML 2.Sequence Diagram 3.同步块设置与锁处理 采用了生产者-消费者模式,用共享对象来连接不同的线程. 第一次作业中,我有三个线程:Receive ...