基于ESP-IDF4.1

  1. #include <esp_wifi.h>
  2. #include <esp_event.h>
  3. #include <esp_log.h>
  4. #include <esp_system.h>
  5. #include <nvs_flash.h>
  6. #include <sys/param.h>
  7. #include "nvs_flash.h"
  8. #include "esp_netif.h"
  9. #include "esp_eth.h"
  10. #include "protocol_examples_common.h"
  11.  
  12. #include <esp_http_server.h>
  13.  
  14. /*
  15. * 演示服务端创建get和post处理服务
  16. */
  17.  
  18. static const char *TAG = "example";
  19.  
  20. /* HTTP GET 处理程序 */
  21. static esp_err_t hello_get_handler(httpd_req_t *req)
  22. {
  23. char* buf;
  24. size_t buf_len;
  25.  
  26. //获取消息头值得长度并且分配内存,而外1个字节存储null终止符
  27. buf_len = httpd_req_get_hdr_value_len(req, "Host") + 1;
  28. if (buf_len > 1) {
  29. buf = malloc(buf_len);
  30. /* 将null结尾的字符串值复制到缓冲区 */
  31. if (httpd_req_get_hdr_value_str(req, "Host", buf, buf_len) == ESP_OK) {
  32. ESP_LOGI(TAG, "Found header => Host: %s", buf);
  33. }
  34. free(buf);
  35. }
  36.  
  37. buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-2") + 1;
  38. if (buf_len > 1) {
  39. buf = malloc(buf_len);
  40. if (httpd_req_get_hdr_value_str(req, "Test-Header-2", buf, buf_len) == ESP_OK) {
  41. ESP_LOGI(TAG, "Found header => Test-Header-2: %s", buf);
  42. }
  43. free(buf);
  44. }
  45.  
  46. buf_len = httpd_req_get_hdr_value_len(req, "Test-Header-1") + 1;
  47. if (buf_len > 1) {
  48. buf = malloc(buf_len);
  49. if (httpd_req_get_hdr_value_str(req, "Test-Header-1", buf, buf_len) == ESP_OK) {
  50. ESP_LOGI(TAG, "Found header => Test-Header-1: %s", buf);
  51. }
  52. free(buf);
  53. }
  54.  
  55. // 读取URL查询字符串长度并分配内存空间
  56. buf_len = httpd_req_get_url_query_len(req) + 1;
  57. if (buf_len > 1) {
  58. buf = malloc(buf_len);
  59. if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
  60. ESP_LOGI(TAG, "Found URL query => %s", buf);
  61. char param[32];
  62. // 从查询字符串获取键值
  63. if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
  64. ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
  65. }
  66. if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
  67. ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
  68. }
  69. if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
  70. ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
  71. }
  72. }
  73. free(buf);
  74. }
  75.  
  76. /* 设置自定义消息头 */
  77. httpd_resp_set_hdr(req, "Custom-Header-1", "Custom-Value-1");
  78. httpd_resp_set_hdr(req, "Custom-Header-2", "Custom-Value-2");
  79.  
  80. //用户上下文通过字符串响应自定义消息头和消息体
  81. const char* resp_str = (const char*) req->user_ctx;
  82. httpd_resp_send(req, resp_str, strlen(resp_str));
  83.  
  84. //检查http请求消息头是否可以被读取
  85. if (httpd_req_get_hdr_value_len(req, "Host") == 0) {
  86. ESP_LOGI(TAG, "Request headers lost");
  87. }
  88. return ESP_OK;
  89. }
  90.  
  91. static const httpd_uri_t hello = {
  92. .uri = "/hello",
  93. .method = HTTP_GET,
  94. .handler = hello_get_handler,
  95. .user_ctx = "Hello World!"
  96. };
  97.  
  98. /* HTTP POST处理 */
  99. static esp_err_t echo_post_handler(httpd_req_t *req)
  100. {
  101. char buf[100];
  102. int ret, remaining = req->content_len;
  103.  
  104. while (remaining > 0) {
  105. /* Read the data for the request */
  106. if ((ret = httpd_req_recv(req, buf,
  107. MIN(remaining, sizeof(buf)))) <= 0) {
  108. if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
  109. /* Retry receiving if timeout occurred */
  110. continue;
  111. }
  112. return ESP_FAIL;
  113. }
  114.  
  115. /* Send back the same data */
  116. httpd_resp_send_chunk(req, buf, ret);
  117. remaining -= ret;
  118.  
  119. /* Log data received */
  120. ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
  121. ESP_LOGI(TAG, "%.*s", ret, buf);
  122. ESP_LOGI(TAG, "====================================");
  123. }
  124.  
  125. // End response
  126. httpd_resp_send_chunk(req, NULL, 0);
  127. return ESP_OK;
  128. }
  129.  
  130. static const httpd_uri_t echo = {
  131. .uri = "/echo",
  132. .method = HTTP_POST,
  133. .handler = echo_post_handler,
  134. .user_ctx = NULL
  135. };
  136.  
  137. /*
  138. * 自定义错误处理
  139. */
  140. esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
  141. {
  142. if (strcmp("/hello", req->uri) == 0) {
  143. httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
  144. /* Return ESP_OK to keep underlying socket open */
  145. return ESP_OK;
  146. } else if (strcmp("/echo", req->uri) == 0) {
  147. httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/echo URI is not available");
  148. /* Return ESP_FAIL to close underlying socket */
  149. return ESP_FAIL;
  150. }
  151. /* For any other URI send 404 and close socket */
  152. httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
  153. return ESP_FAIL;
  154. }
  155.  
  156. /*
  157. * HTTP POST处理程序
  158. */
  159. static esp_err_t ctrl_put_handler(httpd_req_t *req)
  160. {
  161. char buf;
  162. int ret;
  163.  
  164. if ((ret = httpd_req_recv(req, &buf, 1)) <= 0) {
  165. if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
  166. httpd_resp_send_408(req);
  167. }
  168. return ESP_FAIL;
  169. }
  170.  
  171. if (buf == '0') {
  172. /* URI handlers can be unregistered using the uri string */
  173. ESP_LOGI(TAG, "Unregistering /hello and /echo URIs");
  174. httpd_unregister_uri(req->handle, "/hello");
  175. httpd_unregister_uri(req->handle, "/echo");
  176. /* Register the custom error handler */
  177. httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, http_404_error_handler);
  178. }
  179. else {
  180. ESP_LOGI(TAG, "Registering /hello and /echo URIs");
  181. httpd_register_uri_handler(req->handle, &hello);
  182. httpd_register_uri_handler(req->handle, &echo);
  183. /* Unregister custom error handler */
  184. httpd_register_err_handler(req->handle, HTTPD_404_NOT_FOUND, NULL);
  185. }
  186.  
  187. /* Respond with empty body */
  188. httpd_resp_send(req, NULL, 0);
  189. return ESP_OK;
  190. }
  191.  
  192. static const httpd_uri_t ctrl = {
  193. .uri = "/ctrl",
  194. .method = HTTP_PUT,
  195. .handler = ctrl_put_handler,
  196. .user_ctx = NULL
  197. };
  198.  
  199. //启动web服务
  200. static httpd_handle_t start_webserver(void)
  201. {
  202. httpd_handle_t server = NULL;
  203. httpd_config_t config = HTTPD_DEFAULT_CONFIG();
  204.  
  205. // 启动httpd服务
  206. ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
  207. if (httpd_start(&server, &config) == ESP_OK) {
  208. // 设置URI处理程序
  209. ESP_LOGI(TAG, "Registering URI handlers");
  210. httpd_register_uri_handler(server, &hello);
  211. httpd_register_uri_handler(server, &echo);
  212. httpd_register_uri_handler(server, &ctrl);
  213. return server;
  214. }
  215.  
  216. ESP_LOGI(TAG, "Error starting server!");
  217. return NULL;
  218. }
  219.  
  220. //停止web服务
  221. static void stop_webserver(httpd_handle_t server)
  222. {
  223. // 停止httpd服务
  224. httpd_stop(server);
  225. }
  226.  
  227. //断网处理程序
  228. static void disconnect_handler(void* arg, esp_event_base_t event_base,
  229. int32_t event_id, void* event_data)
  230. {
  231. httpd_handle_t* server = (httpd_handle_t*) arg;
  232. if (*server) {
  233. ESP_LOGI(TAG, "Stopping webserver");
  234. stop_webserver(*server);
  235. *server = NULL;
  236. }
  237. }
  238.  
  239. //联网处理程序
  240. static void connect_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
  241. {
  242. httpd_handle_t* server = (httpd_handle_t*) arg;
  243. if (*server == NULL) {
  244. ESP_LOGI(TAG, "Starting webserver");
  245. *server = start_webserver();
  246. }
  247. }
  248.  
  249. //入口
  250. void app_main(void)
  251. {
  252. static httpd_handle_t server = NULL;
  253.  
  254. ESP_ERROR_CHECK(nvs_flash_init());
  255. ESP_ERROR_CHECK(esp_netif_init());
  256. ESP_ERROR_CHECK(esp_event_loop_create_default());
  257.  
  258. ESP_ERROR_CHECK(example_connect());
  259.  
  260. /*
  261. * 注册事件处理服务,当断开网络时停止服务,当连接网络时重启
  262. */
  263. #ifdef CONFIG_EXAMPLE_CONNECT_WIFI
  264. //连接wifi
  265. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
  266. ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
  267. #endif
  268.  
  269. #ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
  270. //连接以太网
  271. ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
  272. ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
  273. #endif
  274.  
  275. //启动服务
  276. server = start_webserver();
  277. }

需要包含的文件: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. Spring的基础配置,以及注解

    常用依赖 <dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webm ...

  2. TensorFlow用法

    TensorFlow用法 什么是TensorFlow TensorFlow是一个开源软件库,用于使用数据流图进行数值计算.图中的节点表示数学运算,而图的边缘表示流动的多维数据数组(张量).这种灵活的体 ...

  3. H.265视频编码与技术全析(下)

    H.265视频编码与技术全析(下) 四.帧内预测模式 共35个(h264有9个),包括Planar,DC,33个方向模式: 除了Intra_Angular预测外,HEVC还和H.264/MPEG-4 ...

  4. AlexeyAB DarkNet YOLOv3框架解析与应用实践(五)

    AlexeyAB DarkNet YOLOv3框架解析与应用实践(五) RNNs in Darknet 递归神经网络是表示随时间变化的数据的强大模型.为了更好地介绍RNNs,我强烈推荐Andrej K ...

  5. Tensor基础实践

    Tensor基础实践 飞桨(PaddlePaddle,以下简称Paddle)和其他深度学习框架一样,使用Tensor来表示数据,在神经网络中传递的数据均为Tensor. Tensor可以将其理解为多维 ...

  6. 英特尔Intel® Arria® 10 FPGA加速器设计

    英特尔Intel Arria 10 FPGA加速器设计 Introducing the Intel Vision Accelerator Design with Intel Arria 10 FPGA ...

  7. MEMS传感器作为变革的驱动力

    MEMS sensors as drivers for change 物联网(IoT)正在改变与周围世界互动的方式.每个人,每件事,都是相互联系的,很快就会相互联系.微机电系统(MEMS)设备和传感器 ...

  8. 容斥+dp (一)

    ARC115 E AtCoder Problem Statement Given is a sequence of \(N\) integers \(A_1\),\(A_2\),...,\(A_N\) ...

  9. mybatis——解决属性名和数据库字段名不一致问题

    首先说一下,我的数据库名字叫mybatis,里边有一张user表,表中有三个字段,id.name.pwd:然后实体类中对应三个属性id.name.password(id和name跟数据库字段名一致,但 ...

  10. RabbitMQ由浅入深入门全总结(一)

    写在最前面 距离上一次发文章已经很久了,其实这段时间一直也没有停笔,只不过在忙着找工作还有学校结课的事情,重新弄了一下博客,后面也会陆陆续续会把文章最近更新出来~ 这篇文章有点长,就分了两篇Q PS: ...