ESP8266--Arduino开发(搭建HTTP网络服务器)
文章目錄
- 一、前言
- 二、搭建HTTP網(wǎng)絡(luò)服務(wù)器
- 三、添加一個(gè)簡(jiǎn)單網(wǎng)頁(yè)進(jìn)行交互
- 四、ESP8266WebServer庫(kù)
- 4.1、WebServer管理方法
- 1、創(chuàng)建Web Server
- 2、啟動(dòng)Web Server
- 3、關(guān)閉Web Server
- 4.2、配置client請(qǐng)求處理方法
- 1、請(qǐng)求響應(yīng)回調(diào)
- 2、配置無(wú)效url的handler
- 3、配置處理文件上傳的handler
- 4.3、獲取請(qǐng)求方法
- 1、獲取請(qǐng)求的url
- 2、獲取請(qǐng)求方法
- 3、獲取請(qǐng)求參數(shù)的值
- 4、獲取請(qǐng)求參數(shù)的名稱
- 5、獲取參數(shù)個(gè)數(shù)
- 6、是否存在某個(gè)參數(shù)
- 7、設(shè)置需要收集的請(qǐng)求頭
- 8、獲取請(qǐng)求頭參數(shù)
- 9、獲取請(qǐng)求頭名字
- 10、獲取請(qǐng)求頭個(gè)數(shù)
- 11、判斷是否存在某個(gè)請(qǐng)求頭
- 12、獲取請(qǐng)求頭Host的值
- 13、認(rèn)證校驗(yàn)
- 14、處理http請(qǐng)求
- 4.4、獲取client請(qǐng)求方法
- 1、處理文件上傳
- 2、設(shè)置響應(yīng)頭
- 3、設(shè)置響應(yīng)體長(zhǎng)度
- 4、發(fā)送響應(yīng)內(nèi)容
- 5、發(fā)送響應(yīng)文件流
- 6、發(fā)送響應(yīng)數(shù)據(jù)
一、前言
超文本傳輸協(xié)議(Hyper Text Transfer Protocol,HTTP)是一個(gè)簡(jiǎn)單的請(qǐng)求-響應(yīng)協(xié)議,它通常運(yùn)行在TCP之上,它指定了客戶端可能發(fā)送給服務(wù)器什么樣的消息以及得到什么樣的響應(yīng),,我們使用瀏覽器打開的網(wǎng)頁(yè)使用的就是HTTP協(xié)議。
接下來(lái)我們會(huì)參數(shù)在ESP8266-NodeMCU上建立一個(gè)HTTP網(wǎng)絡(luò)服務(wù)器,然后通過(guò)瀏覽器來(lái)訪問它。
二、搭建HTTP網(wǎng)絡(luò)服務(wù)器
/*ESP8266-NodeMCU作為HttpServer服務(wù)器 */#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi庫(kù) #include <ESP8266WebServer.h> // web服務(wù)器通信庫(kù)需要使用/* 1. 設(shè)置Wifi接入信息 */ const char* ssid = "LaiFu"; // 需要連接到的WiFi名 const char* password = "wangjichuan"; // 連接的WiFi密碼/* 2. 創(chuàng)建一個(gè)web服務(wù)器對(duì)象,使用80端口,HTTP網(wǎng)絡(luò)服務(wù)器標(biāo)準(zhǔn)端口號(hào)即為80 */ ESP8266WebServer esp8266_server(80);/* 3. 處理訪問網(wǎng)站根目錄“/”的訪問請(qǐng)求 */ void handleRoot() { esp8266_server.send(200, "text/plain", "Hello from ESP8266"); // NodeMCU將調(diào)用此函數(shù)。 }/* 4. 設(shè)置處理404情況的函數(shù)'handleNotFound' */ void handleNotFound(){ // 當(dāng)瀏覽器請(qǐng)求的網(wǎng)絡(luò)資源無(wú)法在服務(wù)器找到時(shí),esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU將調(diào)用此函數(shù)。 }void setup() {/* 1. 初始化串口通訊波特率為115200*/Serial.begin(115200);/* 2. 開啟wifi連接,連接成功后打印IP地址 */WiFi.mode(WIFI_STA); // 設(shè)置Wifi工作模式為STA,默認(rèn)為AP+STA模式WiFi.begin(ssid, password); // 通過(guò)wifi名和密碼連接到WifiSerial.print("\r\nConnecting to "); // 串口監(jiān)視器輸出網(wǎng)絡(luò)連接信息Serial.print(ssid); Serial.println(" ..."); // 顯示NodeMCU正在嘗試WiFi連接int i = 0; // 檢查WiFi是否連接成功while (WiFi.status() != WL_CONNECTED) // WiFi.status()函數(shù)的返回值是由NodeMCU的WiFi連接狀態(tài)所決定的。 { // 如果WiFi連接成功則返回值為WL_CONNECTEDdelay(1000); // 此處通過(guò)While循環(huán)讓NodeMCU每隔一秒鐘檢查一次WiFi.status()函數(shù)返回值Serial.print("waiting for "); Serial.print(i++); Serial.println("s..."); } Serial.println(""); // WiFi連接成功后Serial.println("WiFi connected!"); // NodeMCU將通過(guò)串口監(jiān)視器輸出"連接成功"信息。Serial.print("IP address: "); // 同時(shí)還將輸出NodeMCU的IP地址。這一功能是通過(guò)調(diào)用Serial.println(WiFi.localIP()); // WiFi.localIP()函數(shù)來(lái)實(shí)現(xiàn)的。該函數(shù)的返回值即NodeMCU的IP地址。/* 3. 開啟http網(wǎng)絡(luò)服務(wù)器功能 */esp8266_server.begin(); // 啟動(dòng)http網(wǎng)絡(luò)服務(wù)器esp8266_server.on("/", handleRoot); // 設(shè)置請(qǐng)求根目錄時(shí)的處理函數(shù)函數(shù)esp8266_server.onNotFound(handleNotFound); // 設(shè)置無(wú)法響應(yīng)時(shí)的處理函數(shù) Serial.println("HTTP esp8266_server started");// 告知用戶ESP8266網(wǎng)絡(luò)服務(wù)功能已經(jīng)啟動(dòng) }void loop() {esp8266_server.handleClient(); // 處理http訪問,需要一直運(yùn)行 }ESP8266連接手機(jī)熱點(diǎn)
打開手機(jī)瀏覽器,輸入ESP8266的IP
顯示Hello FROM esp8266字符串說(shuō)明HTTP服務(wù)器訪問正常
三、添加一個(gè)簡(jiǎn)單網(wǎng)頁(yè)進(jìn)行交互
通過(guò)上面的步驟只是搭建好了HTTP網(wǎng)絡(luò)服務(wù)器的框架,現(xiàn)在嵌入一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)來(lái)試試。
這個(gè)網(wǎng)頁(yè)提供兩個(gè)按鈕:關(guān)燈、開燈
主要是要添加路徑響應(yīng)函數(shù),在函數(shù)中設(shè)置小燈的亮滅
esp8266_server.on()中的路徑對(duì)應(yīng)于表單的提交按鈕action屬性的路徑
/*ESP8266-NodeMCU作為HttpServer服務(wù)器 */#include <ESP8266WiFi.h> // 本程序使用ESP8266WiFi庫(kù) #include <ESP8266WebServer.h> // web服務(wù)器通信庫(kù)需要使用/* 1. 設(shè)置Wifi接入信息 */ const char* ssid = "LaiFu"; // 需要連接到的WiFi名 const char* password = "wangjichuan"; // 連接的WiFi密碼/* 2. 創(chuàng)建一個(gè)web服務(wù)器對(duì)象,使用80端口,HTTP網(wǎng)絡(luò)服務(wù)器標(biāo)準(zhǔn)端口號(hào)即為80 */ ESP8266WebServer esp8266_server(80);/* 3. 處理訪問網(wǎng)站根目錄“/”的訪問請(qǐng)求 */ void handleRoot() { String htmlCode = "<!DOCTYPE html>\n"; htmlCode += " <html>\n";htmlCode += " <head>\n";htmlCode += " <meta charset=\"UTF-8\"/>\n";htmlCode += " <title>ESP8266 Butoon Ctrl</title>\n";htmlCode += " </head>\n"; htmlCode += " <body>\n";htmlCode += " <h2 align=\"center\">esp8266控制開關(guān)</h2>";htmlCode += " <p><form action=\"/LED_OFF\" method=\"POST\" align=\"center\"><input type=\"submit\" value=\"關(guān)燈\"></form></p>\n";htmlCode += " <p><form action=\"/LED_ON\" method=\"POST\" align=\"center\"><input type=\"submit\" value=\"開燈\"></form></p>\n";htmlCode += " </body>\n";htmlCode += " </html>\n";esp8266_server.send(200, "text/html", htmlCode); // NodeMCU將調(diào)用此函數(shù)。 }/* 4. 設(shè)置處理404情況的函數(shù)'handleNotFound' */ void handleNotFound(){ // 當(dāng)瀏覽器請(qǐng)求的網(wǎng)絡(luò)資源無(wú)法在服務(wù)器找到時(shí),esp8266_server.send(404, "text/plain", "404: Not found"); // NodeMCU將調(diào)用此函數(shù)。 }void handle_LED_ON() {Serial.println("handle_LED_ON");digitalWrite(2, LOW); }void handle_LED_OFF() {Serial.println("handle_LED_OFF");digitalWrite(2, HIGH); }void setup() {/* 1. 初始化串口通訊波特率為115200*/Serial.begin(115200);//配置GPIO2為輸出模式pinMode(2, OUTPUT);digitalWrite(2, LOW);/* 2. 開啟wifi連接,連接成功后打印IP地址 */WiFi.mode(WIFI_STA); // 設(shè)置Wifi工作模式為STA,默認(rèn)為AP+STA模式WiFi.begin(ssid, password); // 通過(guò)wifi名和密碼連接到WifiSerial.print("\r\nConnecting to "); // 串口監(jiān)視器輸出網(wǎng)絡(luò)連接信息Serial.print(ssid); Serial.println(" ..."); // 顯示NodeMCU正在嘗試WiFi連接int i = 0; // 檢查WiFi是否連接成功while (WiFi.status() != WL_CONNECTED) // WiFi.status()函數(shù)的返回值是由NodeMCU的WiFi連接狀態(tài)所決定的。 { // 如果WiFi連接成功則返回值為WL_CONNECTEDdelay(1000); // 此處通過(guò)While循環(huán)讓NodeMCU每隔一秒鐘檢查一次WiFi.status()函數(shù)返回值Serial.print("waiting for "); Serial.print(i++); Serial.println("s..."); } Serial.println(""); // WiFi連接成功后Serial.println("WiFi connected!"); // NodeMCU將通過(guò)串口監(jiān)視器輸出"連接成功"信息。Serial.print("IP address: "); // 同時(shí)還將輸出NodeMCU的IP地址。這一功能是通過(guò)調(diào)用Serial.println(WiFi.localIP()); // WiFi.localIP()函數(shù)來(lái)實(shí)現(xiàn)的。該函數(shù)的返回值即NodeMCU的IP地址。/* 3. 開啟http網(wǎng)絡(luò)服務(wù)器功能 */esp8266_server.begin(); // 啟動(dòng)http網(wǎng)絡(luò)服務(wù)器esp8266_server.on("/", handleRoot); // 設(shè)置請(qǐng)求根目錄時(shí)的處理函數(shù)函數(shù)esp8266_server.onNotFound(handleNotFound); // 設(shè)置無(wú)法響應(yīng)時(shí)的處理函數(shù) esp8266_server.on("/LED_ON", handle_LED_ON); // 設(shè)置請(qǐng)求開燈目錄時(shí)的處理函數(shù)函數(shù)esp8266_server.on("/LED_OFF", handle_LED_OFF);// 設(shè)置請(qǐng)求關(guān)燈目錄時(shí)的處理函數(shù)函數(shù)Serial.println("HTTP esp8266_server started");// 告知用戶ESP8266網(wǎng)絡(luò)服務(wù)功能已經(jīng)啟動(dòng) }void loop() {esp8266_server.handleClient(); // 處理http訪問,需要一直運(yùn)行 }在處理根目錄訪問請(qǐng)求函數(shù)handleRoot()中添加了html字符串,所以打開ESP8266的IP就能看到解析的網(wǎng)頁(yè):
- 點(diǎn)擊開燈可以看見開發(fā)板小燈打開;
- 點(diǎn)擊關(guān)燈可以看見開發(fā)板小燈關(guān)閉;
四、ESP8266WebServer庫(kù)
4.1、WebServer管理方法
1、創(chuàng)建Web Server
ESP8266WebServer(IPAddress addr, int port = 80); ESP8266WebServer(int port = 80);//例如:創(chuàng)建一個(gè)web服務(wù)器對(duì)象,使用80端口 ESP8266WebServer esp8266_server(80);- addr:IP地址
- port:端口號(hào)
2、啟動(dòng)Web Server
void begin(); void begin(uint16_t port);//例如:啟動(dòng)Web Server esp8266_server.begin();- port:端口號(hào)
- begin函數(shù)要在配置好各個(gè)請(qǐng)求后使用
3、關(guān)閉Web Server
close(); stop();//例如:關(guān)閉Web Server esp8266_server.close();4.2、配置client請(qǐng)求處理方法
1、請(qǐng)求響應(yīng)回調(diào)
void on(const String &url, THandlerFunction handler);- url:路徑
- handler:對(duì)應(yīng)url的處理函數(shù)
注意:這里的handler函數(shù)是Http_ANY,不區(qū)分GET、POST等
void on(const String &url, HTTPMethod method, THandlerFunction fn);- url:路徑
- method:Http請(qǐng)求方法(HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, TTP_DELETE, HTTP_OPTIONS)
- fn:對(duì)應(yīng)url的處理函數(shù)
- url:路徑
- method:Http請(qǐng)求方法(HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, TTP_DELETE, HTTP_OPTIONS)
- fn:對(duì)應(yīng)url的處理函數(shù)
- ufn:文件上傳處理函數(shù)
2、配置無(wú)效url的handler
void onNotFound(THandlerFunction fn);- fn:對(duì)應(yīng)的處理函數(shù)
注意:當(dāng)找不到相對(duì)于的http請(qǐng)求處理函數(shù)時(shí)會(huì)調(diào)用該函數(shù)配置的fn方法
3、配置處理文件上傳的handler
void onFileUpload(THandlerFunction fn);- fn:對(duì)應(yīng)的處理函數(shù)
4.3、獲取請(qǐng)求方法
1、獲取請(qǐng)求的url
String url();2、獲取請(qǐng)求方法
HTTPMethod method()- 返回值: HTTP_ANY, HTTP_GET, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS
3、獲取請(qǐng)求參數(shù)的值
String arg(String name);- name:根據(jù)關(guān)鍵字name獲取請(qǐng)求參數(shù)的值
- i:獲取第i個(gè)請(qǐng)求參數(shù)的值
4、獲取請(qǐng)求參數(shù)的名稱
String arg(int i);- i:獲取第i個(gè)請(qǐng)求參數(shù)的名稱
5、獲取參數(shù)個(gè)數(shù)
int args();6、是否存在某個(gè)參數(shù)
bool hasArg(String name);- name:參數(shù)的名稱
7、設(shè)置需要收集的請(qǐng)求頭
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);- headerkeys[]:請(qǐng)求頭的名字
- headerkeysCount:請(qǐng)求頭的個(gè)數(shù)
8、獲取請(qǐng)求頭參數(shù)
String header(String name);- name:請(qǐng)求頭名稱
- i:獲取第i個(gè)請(qǐng)求頭參數(shù)
9、獲取請(qǐng)求頭名字
String headerName(int i);- i:獲取第i個(gè)請(qǐng)求頭名字
10、獲取請(qǐng)求頭個(gè)數(shù)
int headers();11、判斷是否存在某個(gè)請(qǐng)求頭
bool hasHeader(String name);12、獲取請(qǐng)求頭Host的值
String hostHeader();13、認(rèn)證校驗(yàn)
bool authenticate(const char * username, const char * password);- username: 用戶賬號(hào)
- password: 用戶密碼
14、處理http請(qǐng)求
void handleClient();4.4、獲取client請(qǐng)求方法
1、處理文件上傳
HTTPUpload& upload(); //實(shí)例說(shuō)明 非完整代碼,無(wú)法直接運(yùn)行,理解即可 /*** 處理文件上傳 HandlerFunction* 此方法會(huì)在文件上傳過(guò)程中多次回調(diào),我們可以判斷上傳狀態(tài)*/ void handleFileUpload() {//判斷http requestUriif (server.uri() != "/edit") {return;}//獲得 Http上傳文件處理對(duì)象HTTPUpload& upload = server.upload();//文件開始上傳if (upload.status == UPLOAD_FILE_START) {String filename = upload.filename;if (!filename.startsWith("/")) {filename = "/" + filename;}DBG_OUTPUT_PORT.print("handleFileUpload Name: "); DBG_OUTPUT_PORT.println(filename);//本地文件系統(tǒng)創(chuàng)建一個(gè)文件用來(lái)保存內(nèi)容fsUploadFile = SPIFFS.open(filename, "w");filename = String();} else if (upload.status == UPLOAD_FILE_WRITE) {//文件開始寫入文件//DBG_OUTPUT_PORT.print("handleFileUpload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);if (fsUploadFile) {//寫入文件fsUploadFile.write(upload.buf, upload.currentSize);}} else if (upload.status == UPLOAD_FILE_END) {//文件上傳結(jié)束if (fsUploadFile) {fsUploadFile.close();}DBG_OUTPUT_PORT.print("handleFileUpload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);} }//注冊(cè)文件上傳處理回調(diào) server.on("/edit", HTTP_POST, []() {server.send(200, "text/plain", "");}, handleFileUpload);2、設(shè)置響應(yīng)頭
void sendHeader(const String& name, const String& value, bool first = false);- name: 響應(yīng)頭名
- value: 響應(yīng)頭值
- first: 是否需要放在第一行
3、設(shè)置響應(yīng)體長(zhǎng)度
void setContentLength(const size_t contentLength);4、發(fā)送響應(yīng)內(nèi)容
void sendContent(const String& content); void sendContent_P(PGM_P content); void sendContent_P(PGM_P content, size_t size);5、發(fā)送響應(yīng)文件流
size_t streamFile(T &file, const String& contentType);- file: 具體文件
- contentType: 響應(yīng)類型
6、發(fā)送響應(yīng)數(shù)據(jù)
void send(int code, const char* content_type = NULL, const String& content = String("")); void send(int code, char* content_type, const String& content); void send(int code, const String& content_type, const String& content); void send_P(int code, PGM_P content_type, PGM_P content); void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);- code: 響應(yīng)狀態(tài)碼
- content_type: 響應(yīng)內(nèi)容類型
- content:具體響應(yīng)內(nèi)容
總結(jié)
以上是生活随笔為你收集整理的ESP8266--Arduino开发(搭建HTTP网络服务器)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: winscp用密钥连接linux服务器和
- 下一篇: 如何登录企业邮箱?