ESP8266是个集成了LWIP协议栈的WIFI模块,利用它很容易就完成了物联网的功能。

要搭建web服务器就必须支持HTTP协议。

但是ESP8266官网提供的例子只能支持TCP,不直接支持HTTP。

那么,就需要自己利用TCP来完成HTTP的请求包和响应包。

一、搭建ESP8266的SDK开发环境。

下载并安装集成IDE,AiThinkerIDE_V0.5。

下载并安装Flash下载工具。

下载并解压官方提供的SDK例子,ESP8266 NONOS SDK。

二、利用IoT Demo来完成TCP协议。

进入esp8266_nonos_sdk目录,把driver_lib目录改名为app,把examples->IoT_Demo中的所有文件及文件夹都拷贝到app目录下(直接覆盖)。

在AiThinker_IDE下,打开esp8266_nonos_sdk工程,编译(Build Project),生成.bin文件。

用ESPFlashDownloadTool烧写该.bin文件,可以在WiFi中看到ESP8266的热点,此为开放热点,可以直接连接。

每次编译成功,IDE都会提示.bin文件的烧写地址,如下图所示,eagle.flash.bin->0x00000,eagle.rom0text.bin->0x10000,把这些文件的路径和地址填在烧写工具就可以了。

把ESP8266的GPIO0置低,GPIO2置高,GPIO15置低,重新上电,即可进入烧写模式。

能看到ESP8266的热点,说明硬件已经没有问题了。接下来要修改SDK的源码。

三、利用TCP协议来完成HTTP协议。

在NONOS工程中新建user_tcpserver.c文件,并添加下面的代码。

#include "osapi.h"
#include "at_custom.h"
#include "user_interface.h"
#include "espconn.h"
#include "ets_sys.h"
#include "mem.h"uint8_t http_head[] = {"HTTP/1.0 200 OK\r\n"\"Content-Type: text/html;charset=gbk\r\n"\"Cache-Control: private\r\n"\"Connection: close\r\n"\"\r\n"\"<!DOCTYPE html>"\"<html>" \"<head>"   \"<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" \"<meta name=\"viewport\" content=\"width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;\">" \"<meta name=\"renderer\" content=\"webkit|ie-comp|ie-stand\">"   \"<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">"   \"<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">"    \"<meta name=\"format-detection\" content=\"telephone=no\">" \"<meta content=\"email=no\" name=\"format-detection\" />"   \"<title></title>"    \"</head>"  \"<style type=\"text/css\">" \"body{overflow-x:hidden;}"   \"img{width: 100%;display: block;}"   \"</style>" \"<body>"   \"<a>点击按钮</a>"    \"<form action=\"\" method=\"post\">" \"<button name=\"btn\" value=\"down\">下载</button>"  \"</form>"  \"</body>"  \"</html>"  \""};struct espconn tcpserver;
uint8_t http_data[] = {"HTTP/1.1 200 OK\r\n"\"Content-Type:text/plain;charset=UTF-8\r\n"\"Content-Disposition:attachment;filename=1.txt\r\n"\"\r\n"\"get data"\"\r\n"
};void ICACHE_FLASH_ATTR
tcpserver_recon_cb(void *arg, sint8 errType)//异常断开回调
{struct espconn *pespconn = (struct espconn *)arg;os_printf("\r\n异常断开");
}void ICACHE_FLASH_ATTR
tcpserver_discon_cb(void *arg)//正常断开回调
{struct espconn *pespconn = (struct espconn *)arg;os_printf("\r\n正常断开");
}void ICACHE_FLASH_ATTR
tcpclient_sent_cb(void *arg)//发送回调
{struct espconn *pespconn = (struct espconn *)arg;espconn_disconnect(pespconn);//断开连接os_printf("\r\n发送回调");
}void ICACHE_FLASH_ATTR
tcpserver_recv(void *arg, char *pdata, unsigned short len)//接收函数
{char * http_flg = NULL;unsigned short i,web_len = 0;struct espconn *pespconn = (struct espconn *)arg;os_printf("\r\n接收函数,%s",pdata);http_flg = strstr(pdata,"btn=down");if (http_flg != NULL) {espconn_send(pespconn, http_data, sizeof(http_data));} else {http_flg = strstr(pdata,"HTTP");if(http_flg != NULL){espconn_send(pespconn,http_head,sizeof(http_head));}}}void ICACHE_FLASH_ATTR
tcpserver_listen(void *arg)//服务器被链接回调
{struct espconn *pespconn = (struct espconn *)arg;espconn_regist_reconcb(pespconn, tcpserver_recon_cb);//开启异常断开回调espconn_regist_disconcb(pespconn, tcpserver_discon_cb);//开启正常断开回调espconn_regist_recvcb(pespconn, tcpserver_recv);//开启接收回调espconn_regist_sentcb(pespconn, tcpclient_sent_cb);//开启发送成功回调
}void ICACHE_FLASH_ATTR
tcp_server(void)//开启tcp服务器
{tcpserver.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));tcpserver.proto.tcp->local_port = 80;//监听本地端口号tcpserver.type = ESPCONN_TCP;tcpserver.state = ESPCONN_NONE;espconn_regist_connectcb(&tcpserver, tcpserver_listen);//链接成功回调espconn_accept(&tcpserver);//开启TCP服务器espconn_regist_time(&tcpserver, 1, 0);//设置服务器超时时间为1秒
}

把user_main.c全部改为下面的代码。

#include "ets_sys.h"
#include "osapi.h"#include "user_interface.h"#include "user_devicefind.h"
#include "user_webserver.h"#include "driver/uart.h"
#if ESP_PLATFORM
#include "user_esp_platform.h"
#endifuint32 priv_param_start_sec;struct softap_config softap_cfg;
uint8 ssid[]="esp8266_wifi";         //wifi名
uint8 password[]="12345678";     //wifi密码void ICACHE_FLASH_ATTR
user_set_softap_config(void)
{wifi_softap_get_config(&softap_cfg); // Get config first.wifi_set_opmode(SOFTAP_MODE);           //设置为AP MODEos_strcpy(softap_cfg.ssid, ssid);          //ssid名称os_strcpy(softap_cfg.password, password);  //密码softap_cfg.authmode = AUTH_WPA_WPA2_PSK;softap_cfg.ssid_len = 0; // or its actual lengthsoftap_cfg.max_connection = 4; // how many stations can connect to ESP8266 softAP at most.wifi_softap_set_config(&softap_cfg);      //设置WIFI帐号和密码
}/******************************************************************************* FunctionName : user_rf_cal_sector_set* Description  : SDK just reversed 4 sectors, used for rf init data and paramters.*                We add this function to force users to set rf cal sector, since*                we don't know which sector is free in user's application.*                sector map for last several sectors : ABCCC*                A : rf cal*                B : rf init data*                C : sdk parameters* Parameters   : none* Returns      : rf cal sector
*******************************************************************************/
uint32 ICACHE_FLASH_ATTR
user_rf_cal_sector_set(void)
{enum flash_size_map size_map = system_get_flash_size_map();uint32 rf_cal_sec = 0;switch (size_map) {case FLASH_SIZE_4M_MAP_256_256:rf_cal_sec = 128 - 5;priv_param_start_sec = 0x3C;break;case FLASH_SIZE_8M_MAP_512_512:rf_cal_sec = 256 - 5;priv_param_start_sec = 0x7C;break;case FLASH_SIZE_16M_MAP_512_512:rf_cal_sec = 512 - 5;priv_param_start_sec = 0x7C;break;case FLASH_SIZE_16M_MAP_1024_1024:rf_cal_sec = 512 - 5;priv_param_start_sec = 0xFC;break;case FLASH_SIZE_32M_MAP_512_512:rf_cal_sec = 1024 - 5;priv_param_start_sec = 0x7C;break;case FLASH_SIZE_32M_MAP_1024_1024:rf_cal_sec = 1024 - 5;priv_param_start_sec = 0xFC;break;case FLASH_SIZE_64M_MAP_1024_1024:rf_cal_sec = 2048 - 5;priv_param_start_sec = 0xFC;break;case FLASH_SIZE_128M_MAP_1024_1024:rf_cal_sec = 4096 - 5;priv_param_start_sec = 0xFC;break;default:rf_cal_sec = 0;priv_param_start_sec = 0;break;}return rf_cal_sec;
}void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{
}void esp_init_ok(void)
{uart0_sendStr("Hello Esp8266!\r\n");tcp_server();//开启tcp服务器
}/******************************************************************************* FunctionName : user_init* Description  : entry of user application, init user function here* Parameters   : none* Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_init(void)
{uart_init(BIT_RATE_115200,BIT_RATE_115200);user_set_softap_config();  //set STATION configsystem_init_done_cb(esp_init_ok);#ifdef SERVER_SSL_ENABLEuser_webserver_init(SERVER_SSL_PORT);
#else
//    user_webserver_init(SERVER_PORT);
#endif
}

这样,就实现带密码的WiFi热点,在浏览器打开192.168.4.1即可看到网页,点击下载按钮能下载到一个txt文件。

苹果手机由于权限问题不能下载到txt,安卓手机可以下载到txt。

四、其它问题。

1、如何写网页?

下载一个Dreamweaver来编写你的网页。

然后使用小工具把html语言转成c语言,HTML转化成c语言数组,这个小工具转换出来的C语言可能出错,自己检测一下转义字符就可以了。

把生成的c语言数组替换上面源码中的http_head中的内容即可,但是以下的内容不变。

"HTTP/1.0 200 OK\r\n"\
        "Content-Type: text/html;charset=gbk\r\n"\
        "Cache-Control: private\r\n"\
        "Connection: close\r\n"\
        "\r\n"\

2、关于http协议。

由于官方提供的ESP8266 IoT Demo例子只支持TCP协议,所以我们要在TCP协议的基础上实现HTTP协议。

这里用到HTTP协议的请求头和响应头,请参考《HTTP协议简介》、《HTTP权威指南》

3、为什么我的HTTP请求头和响应头不起作用?

需要在每一句请求头和响应头结尾加上"\r\n"。

4、为什么连接ESP8266的热点会很慢?

不要设置为STATIONAP_MODE,这样STA和AP会互相干扰,改为SOFTAP_MODE即可。

5、不支持input表单。

用以上代码,只能支持button提交的Form表单,而不支持input,也不支持获取其它标签的属性,有待完善。

6、串口不正常。

使用CH340串口模块,发现电脑发送到ESP8266的命令不正常,电压拉不低,最低也有2V左右。

后来换了个串口模块,就正常了。下图为不正常的串口模块。

7、设置ESP8266为串口透传模式。

1)  服务端

以下三条可以提前设置好,永久生效
AT+CWMODE=2
AT+RST
AT+CWSAP="ESP8266","0123456789",11,4

单片机至少要设置以下两条
AT+CIPMUX=1
AT+CIPSERVER=1,8080

2)  客户端

以下四条可以提前设置好,永久生效
AT+CWMODE=1
AT+RST
AT+CWJAP="ESP8266","0123456789"
AT+CIPMUX=0

单片机至少要设置以下三条
AT+CIPMODE=1
AT+CIPSTART="TCP","192.168.4.1",8080
AT+CIPSEND

8、之前用SDK写好的服务器代码,电脑可以连接到ESP8266,后面却发现连接不上,一连接就Leave。

电脑忘记ESP8266的WIFI账号,重新输入密码,连接即可。

SP8266搭建简易web相关推荐

  1. node.js搭建简易Web服务器

    node.js搭建简易Web服务器 node.js简介 Node.js 是一个基于V8引擎的JavaScript 运行环境. V8 是为Google Chrome 提供支持的 JavaScript 引 ...

  2. 【script】python3使用http.server搭建简易web服务

    ''' 更详细的web服务搭建可参考django: https://docs.djangoproject.com/zh-hans/2.1/intro/tutorial01/ '''from http. ...

  3. Jenkins + Jmeter 搭建简易CI (自动执行接口测试+发布web报告+发送邮件)

    Jenkins + Jmeter 搭建简易CI (自动执行接口测试+发布web报告+发送邮件) Jenkins可以很方便的实现构建项目之后自动执行其他任务.可以把Jmeter脚本作为任务放在项目之后自 ...

  4. Python简易web静态服务器程序搭建

    Python简易web静态服务器程序搭建 Python自带简易静态web服务器搭建 http.server模块 DIY简易静态web服务器程序搭建 普通版 步骤 具体代码 面向对象版 代码 命令行版 ...

  5. Python之简易Web框架搭建

    Python之简易Web框架搭建 Web框架介绍 WSGI协议 Web框架开发 项目结构 MyWebServer.py 之前的静态服务器代码 WSGI协议的要求 更新代码 framework.py 返 ...

  6. java web 显示项目下的图片_[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)...

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在 six-finger-web 一个Web后端 ...

  7. apache为什么更适合处理动态请求_[适合初中级Java程序员修炼手册从0搭建整个Web项目](一)...

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206种一棵树最好的时间是十年前,其次是现在 six-finger-web 一个Web后端 ...

  8. 如何搭建java web环境_搭建java WEB开发环境和应用

    搭建java WEB开发环境和应用 更新时间:2009年06月07日 02:28:56   作者: 使用Tomcat服务器,使用DBCP数据源搭建Web开发环境 一 使用Tomcat服务器,使用DBC ...

  9. 搭建简易的物联网服务端和客户端-Maibu控制(二十一)

    创建麦布应用程序,麦步按键控制.原理和网页控制差不多,就是麦步访问之前创建的两个buttonclick接口.感谢qs100371大神. 代码地址:https://github.com/ZZES-ZVD ...

最新文章

  1. html5添加随机率,HTML5 canvas  绘制随机曲线 并实现放大功能
  2. 关于RGBDSLAMV2学习、安装、调试过程
  3. 贝叶斯分析好坏_贝叶斯统计 | 第五章第一部分 决策基本概念
  4. Product 1 Modulo N CodeForces - 1514C
  5. mysql8支持myISAM_mysql8 参考手册--优化MyISAM表
  6. 代码更换ui图片_用技术的方式,在UI设计稿中设置随机码,保证高清
  7. 使用构建器模式来帮助您的单元测试
  8. 快捷配置mysql_windows下的mysql的快捷安装方法和简单配置
  9. ROS-Kinetic安装turtlebot-3并仿真
  10. You specified a pre-MSA CPU in your CFLAGS
  11. 测试用例(功能用例)——人员管理、资产入库
  12. 复旦大学:专硕没住宿?我们帮你建!还给补助!
  13. 孙玄达叔:年薪75万的真实技术面试实践攻略(篇章二)
  14. 遥控直升机主旋翼设定
  15. 《VMware vSphere 6.0虚拟化架构实战指南》——1.2 软件定义数据中心介绍
  16. 广告系统数据采集方法介绍
  17. Android手机获取外网ip(by 星空武哥)
  18. 谈一谈PAC学习理论
  19. 云计算是什么通俗解释_什么是云? 解释
  20. 银行都是用什么技术做超级App

热门文章

  1. Python就业前景好不好?为什么学完Python找不到工作?
  2. Linux下配置DNS服务
  3. git找回删除的stash
  4. 网络分析仪 smith圆图调试
  5. CardView属性简介
  6. 2021-2027中国电工仪器仪表市场现状及未来发展趋势
  7. 这一次,Google 终于对 Web 自动化下手了!
  8. python 反转字符串
  9. IEEE754标准浮点数转换
  10. slice,splice,substring,split