零基础入门学用物联网(ESP8266) 第一部分 基础知识篇(四)

参考教程:https://www.bilibili.com/video/BV1L7411c7jw/?spm_id_from=333.1387.favlist.content.click

七、ESP8266作为网络客户端

1、ESP8266作为网络客户端的行为

(1)网络客户端有很多种类型,像日常生活中使用的手机、电脑,以及ESP866-NodeMCU开发板,都可以作为网络客户端,向服务器发出请求。

(2)如果ESP866-NodeMCU作为客户端,接入一个与互联网连接的Wi-Fi网络中,那么ESP866-NodeMCU想要访问其它服务器的网站首页,大致流程如下所示。

2、使用ESP8266HTTPClient库实现网络通讯

(1)HTTPClient类是使用HTTP协议的网络客户端的抽象,该类的成员函数有如下几个(包括但不限于):

①begin函数:初始化HTTP请求并设置目标地址(URL,请求路径),并返回设置结果,True表示准备就绪,False表示URL格式错误或内存不足。

该函数有多种重载形式,最常用的是只有一个参数的重载形式,参数为指定URL的字符串类型数据

②GET函数:使用GET方法发送HTTP请求,并返回服务器响应的状态码,该函数无参数。

③POST函数:使用POST方法发送HTTP请求,并返回服务器响应的状态码,该函数无参数。

④getString函数:获取服务器HTTP响应报文中响应体的内容,以字符串的形式返回,该函数无参数。

⑤end函数:关闭ESP8266与服务器的连接,该函数无参数。

(2)使用ESP8266连接外部服务器,请求网址"http://www.example.com"的信息,其程序流程如下图所示。

(3)将以下示例程序粘贴到代码区中,然后将其编译并上传NodeMCU开发板,这样即可请求网址"http://www.example.com"的信息,并将返回的内容打印在串口监视器中。

cpp 复制代码
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

#define URL "http://www.example.com"  //测试HTTP请求用的URL,注意网址前面必须添加"http://"

void setup() {
  Serial.begin(9600);
 
  WiFi.mode(WIFI_STA);  //设置ESP8266工作模式为无线终端模式
  WiFi.begin("Zevalin_Computer", "00114514");  //连接Wi-Fi
 
  //等待Wi-Fi连接
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi Connected!");
  
  httpClientRequest();   //发送HTTP请求
}
 
void loop(){

}
 
//发送HTTP请求并且将服务器响应通过串口输出
void httpClientRequest(){
 
  //创建 HTTPClient 对象
  HTTPClient httpClient;
 
  //通过begin函数配置请求地址
  httpClient.begin(URL); 
  Serial.print("URL: "); Serial.println(URL);
 
  //通过GET函数启动连接并发送HTTP请求
  int httpCode = httpClient.GET();
  Serial.print("Send GET request to URL: ");
  Serial.println(URL);
  
  //如果服务器响应HTTP_CODE_OK(200),则从服务器获取响应体信息并通过串口输出
  //如果服务器不响应HTTP_CODE_OK(200),则将服务器响应状态码通过串口输出
  if (httpCode == HTTP_CODE_OK) {
    // 使用getString函数获取服务器响应体内容
    String responsePayload = httpClient.getString();
    Serial.println("Server Response Payload: ");
    Serial.println(responsePayload);
  }
  else {
    Serial.println("Server Respose Code:");
    Serial.println(httpCode);
  }
 
  //关闭ESP8266与服务器连接
  httpClient.end();
}

①WiFi.mode(val):配置ESP8266以val参数指定的模式工作,val的可选项有WIFI_OFF(关闭Wi-Fi)、WIFI_STA(无线终端模式)、WIFI_AP(接入点模式)、WIFI_AP_STA(接入点-无线终端双模式)。

②WiFi.begin(ssid, password):控制ESP8266接入Wi-Fi网络,其中ssid参数为Wi-Fi网络名,password为Wi-Fi网络密码。

3、使用WiFiClient库实现网络通讯

(1)WiFiClient类是使用Wi-Fi接入互联网的网络客户端的抽象,它比HTTPClient类的局限性更小(也就是不局限于使用HTTP协议),该类的成员函数有如下几个(包括但不限于):

①print函数:向服务器发送HTTP请求报文,函数参数为字符串类型的报文内容,报文内容需要程序员按照通信协议的格式自行构建(下图所示的是HTTP请求报文格式,CLRF为换行符)。

②connect函数:与服务器建立连接,第一个参数为被连接网络服务器的网址,第二个参数为被连接网络服务器的端口编号(HTTP协议的熟知端口号为80)。

③connected函数:如果ESP8266已与服务器建立连接,则返回True,否则返回False,该函数无参数。

④available函数:如果ESP8266接收到服务器返回的响应信息,则返回True,否则返回False,该函数无参数。

⑤readStringUntil函数:获取服务器返回的响应信息,直到遇到指定字符,返回字符串类型数据,该指定字符即为函数参数。

⑥find函数:获取服务器返回的响应信息,判断响应信息中有没有指定字符串,该指定字符串即为函数参数,有指定字符串则返回True,否则返回False。

(2)使用ESP8266连接外部服务器,请求网址"http://www.example.com"的信息,其程序流程如下图所示。

(3)将以下示例程序粘贴到代码区中,然后将其编译并上传NodeMCU开发板,这样即可请求网址"http://www.example.com"的信息,并将返回的内容打印在串口监视器中。

cpp 复制代码
#include <ESP8266WiFi.h>
 
const char* host = "www.example.com"; // 目标网络服务器地址
const int httpPort = 80;              // http熟知端口号
 
void setup(){
  Serial.begin(9600);
  Serial.println("");
 
  WiFi.mode(WIFI_STA);   //设置ESP8266工作模式为无线终端模式
  WiFi.begin("Zevalin_Computer", "00114514");  //连接Wi-Fi
 
  //等待Wi-Fi连接
  while(WiFi.status() != WL_CONNECTED){
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi Connected!");
  
  wifiClientRequest();  
}
 
void loop(){

}
 
// 向服务器发送HTTP请求
void wifiClientRequest(){
  // 建立Wi-Fi客户端对象,对象名称client
  WiFiClient client;    
 
  // 建立字符串,用于HTTP请求(注意请求行和请求头的格式)
  String httpRequest =  String("GET /") + " HTTP/1.1\r\n" +
                        "Host: " + host + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
  
  // 通过串口输出连接服务器名称,以便查阅连接服务器的网址                      
  Serial.print("Connecting to "); 
  Serial.print(host); 
 
  // 连接网络服务器
  if(client.connect(host, httpPort)){ 
    Serial.println(" Success!");        // 连接成功后串口输出"Success"信息
    
    client.print(httpRequest);          // 向服务器发送HTTP请求
    Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容
    Serial.println(httpRequest);     
    
    // 通过串口输出网络服务器响应信息
    Serial.println("Web Server Response:");        
    while (client.connected() || client.available()){ 
      if (client.available()){
        String line = client.readStringUntil('\n');
        Serial.println(line);
      }
    }
    
    client.stop();                      // 断开与服务器的连接
    Serial.print("Disconnected from "); // 通过串口输出断开连接信息
    Serial.print(host);
    
  }
  else{ 
    Serial.println(" connection failed!");   // 如果连接不成功,则通过串口输出"连接失败"信息
    client.stop();
  }  
}

八、ESP8266 HTTP协议数据通讯

1、客户端向服务器发送数据信息

(1)在这个示例中,两块ESP8266连接同一个Wi-Fi网络,一块作为服务器,另一块作为客户端,ESP8266客户端将会通过HTTP协议向ESP8266服务器发送信息,最终实现的效果是,通过客户端ESP8266开发板上的按键来"遥控"服务器上的LED点亮和熄灭。

①在运行过程中,客户端ESP8266将会实时检测板上的按键状态,并且把按键状态发送给服务器。

②服务器在接收到客户端按键状态后,可以根据客户端按键状态来控制服务器端板上的LED点亮和熄灭。

(2)服务器端程序:

①程序任务:

1接收客户端发来的HTTP请求并且解析信息中的数据信息。

2将解析的数据信息通过串口监视器显示供用户查看。

3将解析的客户端按键状态信息用于控制服务器端板上LED的点亮和熄灭。

②程序框图:

③程序代码:

cpp 复制代码
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>   // 使用WiFiMulti库 
#include <ESP8266WebServer.h>   // 使用WebServer库
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
 
ESP8266WebServer server(80);    // 建立网络服务器对象,该对象用于响应HTTP请求
 
IPAddress local_IP(192, 168, 10, 135); // ESP8266-NodeMCU联网后的IP
IPAddress gateway(192, 168, 10, 1);    // 网关IP(通常网关IP是WiFI路由IP)
IPAddress subnet(255, 255, 255, 0);    // 子网掩码
IPAddress dns(192, 168, 10, 1);        // 局域网DNS的IP(通常局域网DNS的IP是Wi-FI路由的IP)
 
void setup(void){
  Serial.begin(9600);          // 启动串口通讯
  Serial.println("");
 
  pinMode(LED_BUILTIN, OUTPUT);   
  digitalWrite(LED_BUILTIN, HIGH);
  
  // 设置开发板网络环境(配置开发板、网关的IP地址及子网掩码,局域网DNS的IP可选,非必须配置)
  if(!WiFi.config(local_IP, gateway, subnet)) {
    Serial.println("Failed to Config ESP8266 IP"); 
  } 
  
  wifiMulti.addAP("Zevalin_Computer", "00114514");
  wifiMulti.addAP("Zevalin_esp8266", "00114514");
  Serial.println("Connecting ...");
  
  while (wifiMulti.run() != WL_CONNECTED) { 
    delay(250);
    Serial.print('.');
  }
 
  Serial.println('\n');
  Serial.print("Connected to "); Serial.println(WiFi.SSID());
  Serial.print("IP address:\t"); Serial.println(WiFi.localIP());
 
  server.on("/update", handleUpdate);        // 配置处理"/update"请求的函数
  server.begin();                            // 启动网站服务
  Serial.println("HTTP server started");
}
 
void loop(void){
  server.handleClient();                    // 检查http服务器访问
}
 
void handleUpdate(){
  float floatValue = server.arg("float").toFloat();  // 获取客户端发送HTTP信息中的浮点数值
  int intValue = server.arg("int").toInt();          // 获取客户端发送HTTP信息中的整数数值
  int buttonValue = server.arg("button").toInt();    // 获取客户端发送HTTP信息中的按键控制量
  
  server.send(200, "text/plain", "Received");                 // 发送http响应
 
  buttonValue == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH);
 
  // 通过串口监视器输出获取到的变量数值
  Serial.print("floatValue = ");  Serial.println(floatValue);  
  Serial.print("intValue = ");  Serial.println(intValue); 
  Serial.print("buttonValue = ");  Serial.println(buttonValue);   
  Serial.println("=================");    
}

1IPAddress是类对IP地址的抽象,创建IPAddress类时,构造函数的参数为IP地址各组的数值,其中每8位为一组(IPv4)。

2WiFi.config函数用于配置开发板、网关的IP地址及子网掩码,局域网DNS的IP地址是可选参数,非必须配置。

(3)客户端程序:

①程序任务:

1客户端通过HTTP协议向服务器发送信息。

2信息中包含客户端按键开关引脚状态,用于控制服务器板上LED的点亮和熄灭。

3信息中包含测试数据。

②程序框图:

③程序代码:

cpp 复制代码
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>   // 使用WiFiMulti库 
 
#define buttonPin D3            // 按钮引脚D3
 
ESP8266WiFiMulti wifiMulti;     // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
 
bool buttonState;       // 存储客户端按键控制数据
float clientFloatValue; // 存储客户端发送的浮点型测试数据
int clientIntValue;     // 存储客户端发送的整数型测试数据
 
const char* host = "192.168.10.135";   // 即将连接服务器的网址/IP地址
const int httpPort = 80;               // 即将连接服务器的端口
 
void setup(void){
  Serial.begin(9600);
  Serial.println("");
 
  pinMode(buttonPin, INPUT_PULLUP);    // 将按键引脚设置为输入上拉模式
  
  wifiMulti.addAP("Zevalin_Computer", "00114514");
  wifiMulti.addAP("Zevalin_esp8266", "00114514");
  Serial.println("Connecting ...");
  
  while(wifiMulti.run() != WL_CONNECTED){
    delay(250);
    Serial.print('.');
  }
 
  Serial.println('\n');
  Serial.print("Connected to "); Serial.println(WiFi.SSID());
  Serial.print("IP address:\t"); Serial.println(WiFi.localIP());
}
 
void loop(void){
 // 获取按键引脚状态
 buttonState = digitalRead(buttonPin); 
 
 // 改变测试用变量数值用于服务器端接收数据检测
 clientFloatValue += 1.5;
 clientIntValue += 2;
 
 // 向服务器发送请求
 wifiClientRequest();
 delay(1000);
}
 
void wifiClientRequest(){
  WiFiClient client;  
 
  // 将需要发送的数据信息放入客户端请求
  String url = "/update?float=" + String(clientFloatValue) + 
               "&int=" + String(clientIntValue) +
               "&button=" + String(buttonState);
                         
  // 建立字符串,用于HTTP请求
  String httpRequest =  String("GET ") + url + " HTTP/1.1\r\n" +
                        "Host: " + host + "\r\n" +
                        "Connection: close\r\n" +
                        "\r\n";
                        
  Serial.print("Connecting to "); 
  Serial.print(host); 
  
  if (client.connect(host, httpPort)){
    Serial.println(" Sucess");
    
    client.print(httpRequest);           // 向服务器发送HTTP请求
    Serial.println("Sending request: "); // 通过串口输出HTTP请求信息内容
    Serial.println(httpRequest);        
  }
  else{
    Serial.println(" failed");   //如果连接失败则串口输出信息告知用户
  }
  
  client.stop();                         
}

2、客户端向服务器请求数据信息

相关推荐
AGIPlayer5 小时前
没有生态的大模型不算前沿
大数据·人工智能·物联网
TDengine (老段)6 小时前
TDengine 连接算子 — Inner/Outer/ASOF/Window Join 的实现与使用
大数据·数据库·物联网·哈希算法·时序数据库·tdengine·涛思数据
砍材农夫8 小时前
物联网实战|Spring Boot + Netty 搭建 MQTT 消息路由与流转层
java·spring boot·后端·物联网·spring
charlie11451419110 小时前
嵌入式Linux驱动开发——从轮询到中断
linux·开发语言·驱动开发·嵌入式
2023自学中10 小时前
imx6ull开发板,sd卡启动运行linux,手动给开发板的 emmc 做分区、烧系统
linux·嵌入式·开发板
果丁智能10 小时前
物联网智能锁在网约房、民宿领域的落地实践:身份核验与远程授权的全链路技术方案
人工智能·物联网·智能家居
阿泽·黑核10 小时前
05 keyflow 扩展设计方案:矩阵键盘/组合键/事件队列/中断驱动
线性代数·矩阵·计算机外设·嵌入式·agent·vibe coding
by————组态10 小时前
Ricon组态技术架构 - 企业级Web组态解决方案
运维·服务器·前端·物联网·架构·组态·组态软件
by————组态11 小时前
Ricon组态可视化编辑器 - 所见即所得的工业画布
前端·javascript·物联网·架构·编辑器·组态
大鱼>12 小时前
ROS2+AIoT:机器人操作系统的物联网化演进
物联网·机器人