目的
ESP8266可以方便的进行UDP通讯实现通过网络控制设备的功能,但是该方法对于用户来说还需要一个界面来完成数据通讯,所幸ESP系列有着不错的性能和不小的存储空间,足够用来构建简单的网页服务器(Web Server),这样用户就可以通过浏览器访问进行查看数据或控制设备。
开启服务器
在Arduino for esp8266中启用服务功能非常简单,如下两步即可实现:
WiFiServer server(80); //建立服务器对象,设置监听端口号为80(网页默认端口号) server.begin(); //启用服务器
只要上述两步就完成了Server的设置,接下来就是具体的处理工作了。
监听客户端
Server的具体处理事务在loop()函数中进行,首先请看下述代码:
String readString = ""; //建立一个字符串对象用来接收存放来自客户的数据 void loop() {
WiFiClient client = server.available(); //尝试建立客户对象 if (client) //如果当前有客户可用 {
boolean currentLineIsBlank = true; Serial.println("[Client connected]"); while (client.connected()) //如果客户端建立连接 {
if (client.available()) //等待有可读数据 {
char c = client.read(); //读取一字节数据 readString += c; //拼接数据 // if (c == '\n' && currentLineIsBlank) //等待请求头接收完成(接收到空行) {
break; } if (c == '\n') {
currentLineIsBlank = true; //开始新行 } else if (c != '\r') {
currentLineIsBlank = false; //正在接收某行中 } // } } delay(1); //等待客户完成接收 client.stop(); //结束当前连接: Serial.println("[Client disconnected]"); Serial.println(readString); //打印输出来自客户的数据 readString = ""; } }
以上代码中除去/*/和/*/之间部分代码为监听客户端连接并接收数据功能;/*/和/*/之间部分代码用于对客户端的请求进行处理。将代码烧录到模块中进行测试,可以看到效果如下:

可以看到在浏览器访问Server的时候Server会接收到下面的信息:
Web的请求与响应
实现Web Server功能
//响应头 String responseHeaders = String("") + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Connection: close\r\n" + "\r\n"; //网页
String myhtmlPage = String("") + "Hello World";
然后上文中代码改写如下:
if (c == '\n' && currentLineIsBlank) //等待请求头接收完成(接收到空行) {
//比较接收到的请求数据 if (readString.startsWith("GET / HTTP/1.1")) //如果是网页请求 {
client.print(responseHeaders); //向客户端输出网页响应 client.print(myhtmlPage); //向客户端输出网页内容 client.print("\r\n"); } else {
client.print("\r\n"); } break; }
通过网页收发数据
建立网页
首先我们准备一个网页:
<html> <head> <title>ESP8266 Web Server Test
title> <script defer="defer"> function ledSwitch() {
var xmlhttp; if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest(); } else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("txtState").innerHTML = xmlhttp.responseText; } }, xmlhttp.open("GET", "Switch", true); xmlhttp.send(); }
script>
head> <body> <div id="txtState">Unkwon
div> <input type="button" value="Switch" onclick="ledSwitch()">
body>
html>
完善Web Server功能
下面是完整的需要烧录到ESP8266中的代码:
#include
/* 该工程可以在2.4.0版本esp8266库中运行,没在更高版本库中进行测试 */ const char *ssid = ""; const char *password = ""; WiFiServer server(80); String readString = ""; //建立一个字符串对象用来接收存放来自客户的数据 //响应头 String responseHeaders = String("") + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/html\r\n" + "Connection: close\r\n" + "\r\n"; //网页
String myhtmlPage = String("") + " " + " " + " ESP8266 Web Server Test " + " + " function ledSwitch() {" + " var xmlhttp;" + " if (window.XMLHttpRequest) {" + " xmlhttp = new XMLHttpRequest();" + " } else {" + " xmlhttp = new ActiveXObject(\"Microsoft.XMLHTTP\");" + " }" + " xmlhttp.onreadystatechange = function () {" + " if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {" + " document.getElementById(\"txtState\").innerHTML = xmlhttp.responseText;" + " }" + " }," + " xmlhttp.open(\"GET\", \"Switch\", true);" + " xmlhttp.send(); " + " }" + " " + "" + " " + "
Unkwon
" + " " + "" + ""; bool isLedTurnOpen = false; // 记录LED状态 void setup() {
pinMode(2, OUTPUT); digitalWrite(2, HIGH); // 熄灭LED Serial.begin(); Serial.println(); Serial.printf("Connecting to %s ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print("."); } Serial.println(" connected"); server.begin(); Serial.printf("Web server started, open %s in a web browser\n", WiFi.localIP().toString().c_str()); } void loop() {
WiFiClient client = server.available(); //尝试建立客户对象 if (client) //如果当前有客户可用 {
boolean currentLineIsBlank = true; Serial.println("[Client connected]"); while (client.connected()) //如果客户端建立连接 {
if (client.available()) //等待有可读数据 {
char c = client.read(); //读取一字节数据 readString += c; //拼接数据 // if (c == '\n' && currentLineIsBlank) //等待请求头接收完成(接收到空行) {
//比较接收到的请求数据 if (readString.startsWith("GET / HTTP/1.1")) //如果是网页请求 {
client.print(responseHeaders); //向客户端输出网页响应 client.print(myhtmlPage); //向客户端输出网页内容 client.print("\r\n"); } else if (readString.startsWith("GET /Switch")) //如果是改变LED状态请求 {
if (isLedTurnOpen == false) {
digitalWrite(2, LOW); // 点亮LED client.print("LED has been turn on"); isLedTurnOpen = true; } else {
digitalWrite(2, HIGH); // 熄灭LED client.print("LED has been turn off"); isLedTurnOpen = false; } } else {
client.print("\r\n"); } break; } if (c == '\n') {
currentLineIsBlank = true; //开始新行 } else if (c != '\r') {
currentLineIsBlank = false; //正在接收某行中 } // } } delay(1); //等待客户完成接收 client.stop(); //结束当前连接: Serial.println("[Client disconnected]"); Serial.println(readString); //打印输出来自客户的数据 readString = ""; } }
上面的代码直接拷贝可能网页的字符串部分代码会出现编码问题导致无法正确运行,该部分最好删除重新手打。如果想偷懒的话可以试试只删除 onclick 这个词的 o 然后手打输入。
总结
这篇文章中更多的会涉及一些底层原理相关的内容,想要简单的使用可以参考《从零开始的ESP8266探索(09)-更加方便的ESP8266WebServer使用介绍》
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213331.html原文链接:https://javaforall.net
