Stream– ESP8266物联网应用
Stream对于ESP8266-Arduino语言来说指的是数据序列。请留意:在C++编程中Stream常被翻译作“流”。我们认为将Stream称为数据序列更加直观。因为数据序列这一概念有两个很关键特点。
第一个特点是“序”,即数据序列不能是杂乱无章的数据罗列。
第二个特点是“列”,即数据序列是排成一列的。
代码实例
使用串口监视器演示Stream概念
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : stream_readString
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO朔
- 日期/Date(YYYYMMDD) : 20200308
- 程序目的/Purpose :
- Stream类用于处理字符数据流或二进制数据流。Stream类是不能被直接调用的。
- 然而当我们使用基于Stream类的库时,都会调用Stream中的内容。
-
- 以下Arduino库及相应库中的类都是基于Stream类所实现的。
- 库 类
- Serial Serial
- SoftwareSerial SoftwareSerial
- Ehternet EthernetClient
- ESP8266FS File
- SD File
- Wire Wire
- GSM GSMClient
- WifiClient WiFiClient
- WiFiServer WiFiServer
- WiFiUDP WiFiUDP
- WiFiClientSecure WiFiClientSecure
-
- 此程序使用Serial库来演示Stream类中的available()以及
- readString函数的使用方法。
- available函数将会返回开发板所接收到的stream中等待读取的字节数。
- readString函数将读取stream中的字符并存储到字符中。
- -----------------------------------------------------------------------
- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
- 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
- http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
- ***********************************************************************/
-
- void setup() {
- // 启动串口通讯
- Serial.begin(9600);
- Serial.println();
- }
-
- void loop() {
- if (Serial.available()){ // 当串口接收到信息后
- String serialData = Serial.readString(); // 将接收到的信息使用readString()存储于serialData变量
- Serial.print(serialData); // 以便查看serialData变量的信息
- }
- }
在本示例中,我们使用了
Serial.available
来判断ESP8266开发板是否接收到串口数据。这里的开发板通过串口所接收到的数据就是Stream数据。另外,程序通过Serial.println
语句将接收到的Stream数据通过串口输出并显示在串口监视器中,这里ESP8266通过串口所输出的数据也是Stream数据。换句话说,ESP8266开发板通过串口收发的数据都是Stream数据。
使用HTTP请求和响应信息演示Stream概念
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : wifiClient_request_basic
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : Dapenson
- 日期/Date(YYYYMMDD) : 20200325
- 程序目的/Purpose :
- 此程序用于演示如何使用esp8266作为互联网客户端向www.example.com网站服务器发送http请求,
- 并且将网站服务器响应的信息输出在屏幕中
- -----------------------------------------------------------------------
- 修订历史/Revision History
- 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
- 20200411 CYNO朔 001 将请求服务器改为www.example.com
- -----------------------------------------------------------------------
- 本示例程序为太极创客团队制作的《零基础入门学用物联网》中示例程序。
- 该教程为对物联网开发感兴趣的朋友所设计和制作。如需了解更多该教程的信息,请参考以下网页:
- http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
- ***********************************************************************/
- #include
-
- const char* host = "www.example.com"; // 网络服务器地址
- const int httpPort = 80; // http端口80
-
- // 设置wifi接入信息(请根据您的WiFi信息进行修改)
- const char* ssid = "taichimaker";
- const char* password = "12345678";
-
- void setup() {
- //初始化串口设置
- Serial.begin(9600);
- Serial.println("");
-
- //设置ESP8266工作模式为无线终端模式
- WiFi.mode(WIFI_STA);
-
- //开始连接wifi
- WiFi.begin(ssid, password);
-
- //等待WiFi连接,连接成功打印IP
- while (WiFi.status() != WL_CONNECTED) {
- delay(1000);
- Serial.print(".");
- }
- Serial.println("");
- Serial.println("WiFi Connected!");
-
- wifiClientRequest();
- }
-
- void loop(){}
-
- // 向服务器发送HTTP请求
- void wifiClientRequest(){
- // 建立WiFi客户端对象,对象名称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);
-
- // 连接网络服务器,以下段落中的示例程序为本程序重点1
- // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
- // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
- if (client.connect(host, httpPort)){
- Serial.println(" Success!"); // 连接成功后串口输出“Success”信息
-
- client.print(httpRequest); // 向服务器发送合同谈判请求
- Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
- Serial.println(httpRequest);
-
- // 通过串口输出网络服务器响应信息, 以下段落中的示例程序为本程序重点2
- // 请参考太极创客网站中关于本程序的讲解页面获取详细说明信息。网址:
- // http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-c/esp8266-nodemcu-web-client/http-request/
- 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开发板通过client.readStringUntil来读取服务器响应信息。这里服务器响应信息也是Stream数据
使用File对象演示Stream概念
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : file_stream_demo
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO 朔
- 日期/Date(YYYYMMDD) : 20200506
- 程序目的/Purpose :
- 通过File对象演示Stream操作
- ***********************************************************************/
- #include
-
- String file_name = "/taichi-maker/notes.txt"; //被读取的文件位置和名称
-
- void setup() {
- Serial.begin(9600);
- Serial.println("");
-
- // 启动SPIFFS
- if(SPIFFS.begin()){
- Serial.println("SPIFFS Started.");
- } else {
- Serial.println("SPIFFS Failed to Start.");
- }
-
- File dataFile = SPIFFS.open(file_name, "w");// 建立File对象用于向SPIFFS中的file对象(即/notes.txt)写入信息
- dataFile.println("Hello IOT World."); // 向dataFile写入字符串信息
- dataFile.close(); // 完成文件写入后关闭文件
- Serial.println("Finished Writing data to SPIFFS");
-
- // 使用find函数从dataFile中找到指定信息
- Serial.print("Try to find IOT in ");Serial.println(file_name);
-
- dataFile = SPIFFS.open(file_name, "r"); // 以“r”模式再次打开闪存文件
- if (dataFile.find("IOT")){ // 在闪存文件中查找文字"IOT"
- Serial.print("Found IOT in file: "); // 如果找到则告知用户找到文字"IOT"
- Serial.println(file_name);
- }
-
- // 使用readString读取执行完find函数后的dataFile内容并显示与串口监视器
- Serial.println("Use readString to get contents of dataFile after find");
- Serial.println(dataFile.readString());
-
- dataFile.close(); // 完成操作后关闭文件
- }
-
- void loop() {}
使用
dataFile.find
从闪存文件内容里查找指定信息。使用dataFile.readString
来获取信息。这些操作都是针对Stream数据的操作。
客户端向服务器发送数据信息
使用ESP8266客户端向ESP8266服务器发送数据
ESP8266客户端将会通过HTTP协议向ESP8266服务器发送信息。在运行过程中,客户端ESP8266将会实时检测板上的按键状态,并且把按键状态发送给服务器。服务器在接收到客户端按键状态后,可以根据客户端按键状态来控制服务器端板上的LED点亮和熄灭。最终实现的效果是,我们可以通过客户端ESP8266开发板上的按键来“遥控”服务器上的LED点亮和熄灭。
服务器端程序:
– 接收客户端发来的http请求并且解析信息中的数据信息
– 将解析的数据信息通过串口监视器显示供用户查看
– 将解析的客户端按键状态信息用于控制服务器端板上LED的点亮和熄灭
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : csd_server
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO朔
- 日期/Date(YYYYMMDD) : 20200228
- 程序目的/Purpose :
- 演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
- 一个以客户端模式运行。
-
- 此代码为客户端代码。此代码主要功能:
- - 接收客户端发来的http请求
- - 解析客户端请求中的数据信息
- - 将解析的数据信息通过串口监视器显示供用户查看
- - 将解析的客户端按键状态信息用于控制板上LED的点亮和熄灭
-
- -----------------------------------------------------------------------
- 修订历史/Revision History
- 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
- 20200229 CYNO朔 0.01 加入IP设置
-
- ***********************************************************************/
-
- #include
- #include
// 使用WiFiMulti库 - #include
// 使用WebServer库 -
- ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
-
- ESP8266WebServer server(80); // 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
-
- IPAddress local_IP(192, 168, 0, 123); // 设置ESP8266-NodeMCU联网后的IP
- IPAddress gateway(192, 168, 0, 1); // 设置网关IP(通常网关IP是WiFI路由IP)
- IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
- IPAddress dns(192,168,0,1); // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
-
- void setup(void){
- Serial.begin(9600); // 启动串口通讯
- Serial.println("");
-
- pinMode(LED_BUILTIN, OUTPUT);
- digitalWrite(LED_BUILTIN, HIGH);
-
- // 设置开发板网络环境
- if (!WiFi.config(local_IP, gateway, subnet)) {
- Serial.println("Failed to Config ESP8266 IP");
- }
-
- wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列WiFi ID和密码输入这里
- wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
- wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
- Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
-
- // 尝试进行wifi连接。
- while (wifiMulti.run() != WL_CONNECTED) {
- delay(250);
- Serial.print('.');
- }
-
- // WiFi连接成功后将通过串口监视器输出连接成功信息
- Serial.println('\n');
- Serial.print("Connected to ");
- Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
- Serial.print("IP address:\t");
- Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
-
- server.on("/update", handleUpdate); // 处理服务器更新函数
-
- 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("=================");
- }
客户端程序:
– 客户端通过HTTP协议向服务器发送信息
– 信息中包含客户端按键开关引脚状态用于控制服务器板上LED的点亮和熄灭
– 信息中还包含测试数据以便我们更好的了解如何使用ESP8266发送和接收物联网数据信息
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : csd_client
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO朔
- 日期/Date(YYYYMMDD) : 20200228
- 程序目的/Purpose :
- 演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
- 一个以客户端模式运行。
-
- 此代码为客户端代码。此代码主要功能:
- - 通过HTTP协议向服务器发送HTTP请求
- - HTTP请求中包含客户端按键开关引脚状态和程序测试数据
- -----------------------------------------------------------------------
- 修订历史/Revision History
- 日期/Date 作者/Author 参考号/Ref 修订说明/Revision Description
- -----------------------------------------------------------------------
- http信息发送说明
- 192.168.0.123/update?float=1.5&int=2&button=0
- ***********************************************************************/
- #include
- #include
// 使用WiFiMulti库 -
- #define buttonPin D3 // 按钮引脚D3
-
- ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是 'wifiMulti'
-
- bool buttonState; //存储客户端按键控制数据
- float clientFloatValue; //存储客户端发送的浮点型测试数据
- int clientIntValue; //存储客户端发送的整数型测试数据
-
- const char* host = "192.168.0.123"; // 即将连接服务器网址/IP
- const int httpPort = 80; // 即将连接服务器端口
-
- void setup(void){
- Serial.begin(9600); // 启动串口通讯
- Serial.println("");
-
- pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
-
- wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列WiFi ID和密码输入这里
- wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
- wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
- Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
-
- while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
- delay(250);
- Serial.print('.');
- }
-
- // WiFi连接成功后将通过串口监视器输出连接成功信息
- Serial.println('\n');
- Serial.print("Connected to ");
- Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
- Serial.print("IP address:\t");
- Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
- }
-
- 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)) { //如果连接失败则串口输出信息告知用户然后返回loop
- Serial.println(" Sucess");
-
- client.print(httpRequest); // 向服务器发送HTTP请求
- Serial.println("Sending request: ");// 通过串口输出HTTP请求信息内容以便查阅
- Serial.println(httpRequest);
- } else{
- Serial.println(" failed");
- }
-
- client.stop();
- }
客户端向服务器请求数据信息
客户端会定时向服务器发送请求信息。服务器一旦接收到客户端请求后,会把服务器开发板上的按键引脚状态发送给客户端。客户端在接收到这一信息后,会利用该信息来控制客户端的LED点亮和熄灭。最终实现的效果是,通过控制服务器端的板上按键,我们可以控制客户端板上LED的点亮和熄灭。
使用ESP8266客户端从ESP8266服务器获取数据
服务器端程序:
– 实时获取服务器端开发板上按钮引脚状态
– 当有客户端向ESP8266服务器的/update发送请求时,将服务器的按键引脚状态通过响应信息回复给客户端
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : cgd_server
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO朔
- 日期/Date(YYYYMMDD) : 20200228
- 程序目的/Purpose :
- 演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
- 一个以客户端模式运行。用户可通过服务器端开发板上按钮控制客户端的板上LED点亮和熄灭
-
- 此代码为服务器端代码。此代码主要功能:
- - 实时获取服务器端开发板上按钮引脚状态
- - 当有客户端向ESP8266服务器的/update发送请求时,将服务器的按键引脚状态
- 通过响应信息回复给客户端
- ***********************************************************************/
- #include
// 本程序使用 ESP8266WiFi库 - #include
// ESP8266WiFiMulti库 - #include
// ESP8266WebServer库 -
- #define buttonPin D3 // 按钮引脚D3
-
- ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象,对象名称是'wifiMulti'
-
- ESP8266WebServer esp8266_server(80);// 建立网络服务器对象,该对象用于响应HTTP请求。监听端口(80)
-
- IPAddress local_IP(192, 168, 0, 123); // 设置ESP8266-NodeMCU联网后的IP
- IPAddress gateway(192, 168, 0, 1); // 设置网关IP(通常网关IP是WiFI路由IP)
- IPAddress subnet(255, 255, 255, 0); // 设置子网掩码
- IPAddress dns(192,168,0,1); // 设置局域网DNS的IP(通常局域网DNS的IP是WiFI路由IP)
-
- bool pinState; // 存储引脚状态用变量
-
- void setup(){
- Serial.begin(9600); // 启动串口通讯
- Serial.println("");
-
- pinMode(buttonPin, INPUT_PULLUP); // 将按键引脚设置为输入上拉模式
-
- // 设置开发板网络环境
- if (!WiFi.config(local_IP, gateway, subnet)) {
- Serial.println("Failed to ESP8266 IP");
- }
-
- //通过addAp函数存储 WiFi名称 WiFi密码
- wifiMulti.addAP("taichi-maker1", "12345678"); // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。
- wifiMulti.addAP("taichi-maker2", "87654321"); // 用户可自行增加、修改、删除此处网络连接信息。
- wifiMulti.addAP("taichi-maker3", "13572468");
-
- // 尝试网络连接
- int i = 0;
- while (wifiMulti.run() != WL_CONNECTED) {
- delay(1000);
- Serial.print(i++); Serial.print(' ');
- }
-
- // WiFi连接成功后,通过串口监视器输出连接信息
- Serial.println("");
- Serial.print("Connected to ");
- Serial.println(WiFi.SSID());
- Serial.print("IP address:\t");
- Serial.println(WiFi.localIP());
-
- // 设置网络服务器
- esp8266_server.on("/update", handleUpdate); // 处理客户端HTTP请求LED状态
-
- esp8266_server.begin();
- Serial.println("HTTP esp8266_server started");
- }
-
- void loop(){
- pinState = digitalRead(buttonPin); // 获取引脚状态
- esp8266_server.handleClient(); // 处理http服务器访问
- }
-
- // 处理客户端HTTP请求LED状态button: 1
- void handleUpdate() {
- String pinStateStr;
- pinState == HIGH ? pinStateStr = "1" : pinStateStr = "0";
- esp8266_server.send(200, "text/html", "buttonState: " + pinStateStr);
- }
客户端程序:
– 定时向服务器发送请求,从而获取服务器开发板上按钮状态
– 将服务器端发来的按钮引脚电平状态解析为数字量,并且用该数字量控制板上LED点亮和熄灭
- /**********************************************************************
- 项目名称/Project : 零基础入门学用物联网
- 程序名称/Program name : cgd_client
- 团队/Team : 太极创客团队 / Taichi-Maker (www.taichi-maker.com)
- 作者/Author : CYNO朔
- 日期/Date(YYYYMMDD) : 20200228
- 程序目的/Purpose :
- 演示如何实现两个NodeMCU间通过WiFi进行通讯。两台NodeMCU一个以服务器模式运行,
- 一个以客户端模式运行。
-
- 此代码为客户端代码。此代码主要功能:
- - 定时向服务器发送请求信息,从而获取服务器开发板上按钮状态
- - 将服务器端发来的按钮引脚电平状态解析为数字量,并且用该数字量控制板上LED点亮和熄灭
- ***********************************************************************/
- #include
- #include
-
- ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
-
- const char* host = "192.168.0.123"; // 网络服务器IP
- const int httpPort = 80; // http端口80
-
- void setup(){
- Serial.begin(9600);
- Serial.println("");
-
- pinMode(LED_BUILTIN, OUTPUT);
- digitalWrite(LED_BUILTIN, HIGH);
-
- wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); // 将需要连接的一系列WiFi ID和密码输入这里
- wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
- wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
- Serial.println("Connecting ...");
-
- int i = 0;
- while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
- delay(1000);
- Serial.print(i++); Serial.print(' ');
- }
-
- // WiFi连接成功后将通过串口监视器输出连接成功信息
- Serial.println("");
- Serial.print("Connected to ");
- Serial.println(WiFi.SSID()); // WiFi名称
- Serial.print("IP address:\t");
- Serial.println(WiFi.localIP()); // IP
- }
-
- void loop(){
- wifiClientRequest();
- delay(3000);
- }
-
- void wifiClientRequest(){
- WiFiClient client; // 建立WiFiClient对象
-
- bool buttonState; // 储存服务器按钮状态变量
-
- Serial.print("Connecting to "); Serial.print(host);
-
- // 连接服务器
- if (client.connect(host, httpPort)){
- Serial.println(" Success!");
-
- // 建立客户端请求信息
- String httpRequest = String("GET /update") + " HTTP/1.1\r\n" +
- "Host: " + host + "\r\n" +
- "Connection: close\r\n" +
- "\r\n";
-
- // 发送客户端请求
- Serial.println("Sending request: ");Serial.print(httpRequest);
- client.print(httpRequest);
-
- // 获取服务器响应信息中的按钮状态信息
- while (client.connected() || client.available()){
- if(client.find("buttonState:")){
- buttonState = client.parseInt();
- Serial.print("buttonState: " );
- Serial.println(buttonState);
- }
- }
- } else{
- Serial.println(" failed!");
- }
-
- Serial.println("===============");
- client.stop(); // 停止客户端
-
- // 根据服务器按键状态点亮或熄灭LED
- buttonState == 0 ? digitalWrite(LED_BUILTIN, LOW) : digitalWrite(LED_BUILTIN, HIGH);
- }
HTTP
在 HTTP 请求中,请求行、请求头和请求体是构成请求的三部分,它们各自承担不同的功能。下面是它们的详细解释和作用:
1. 请求行(Request Line)
主要组成部分:
-
请求方法(Request Method):
- 请求方法指定了客户端希望对服务器上的资源执行的操作。常见的 HTTP 请求方法有:
GET
:获取资源。POST
:提交数据。PUT
:更新资源。DELETE
:删除资源。HEAD
:获取资源的头部信息。OPTIONS
:查询支持的请求方法。PATCH
:部分更新资源。
请求方法通常表示客户端想要对服务器上的某个资源进行的操作。
- 请求方法指定了客户端希望对服务器上的资源执行的操作。常见的 HTTP 请求方法有:
-
请求 URI(Request URI):
- 请求 URI 表示客户端要访问的资源的路径或地址。例如,
/home
,/api/user
,/products?id=123
。 - 也可以包含查询参数,如
/search?q=chatgpt&lang=zh
。
- 请求 URI 表示客户端要访问的资源的路径或地址。例如,
-
HTTP 版本(HTTP Version):
- 指定所使用的 HTTP 协议版本,常见的版本是
HTTP/1.1
或HTTP/2
,例如:HTTP/1.1
:最常见的版本。HTTP/2
:性能改进版,支持更高效的多路复用。
- 指定所使用的 HTTP 协议版本,常见的版本是
示例:
GET /index.html HTTP/1.1
意思是:客户端使用 GET
方法请求 /index.html
这个资源,并使用 HTTP/1.1
协议。
请求行中的参数
虽然请求行本身不能直接携带数据,但它可以通过**查询字符串(Query String)**携带一些附加的参数,尤其是在 GET
请求中。例如:
GET /search?q=example&page=2 HTTP/1.1
这里,q=example&page=2
是查询字符串,它作为请求的一部分被附加在 URL 后面,传递给服务器。这类参数属于请求的一部分,但不能看作是请求体中的“数据”。
2. 请求头(Request Headers)
请求头包含了关于客户端环境、请求的附加信息以及如何处理请求的指示。请求头不是必需的,但通常包含很多有用的元信息。
常见的请求头字段:
-
Host:指定服务器的域名和端口号。对于 HTTP/1.1 中的每个请求,
Host
字段是必须的。- 示例:
Host: www.example.com
- 示例:
-
User-Agent:客户端的身份信息,告诉服务器请求是由什么软件发起的(例如浏览器、应用等)。
- 示例:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
- 示例:
-
Accept:告知服务器客户端可以处理的响应内容类型。
- 示例:
Accept: text/html, application/json
- 示例:
-
Content-Type:在发送请求体时,指定请求体的内容类型。例如,
application/json
或application/x-www-form-urlencoded
。- 示例:
Content-Type: application/json
- 示例:
-
Authorization:用于身份验证,向服务器提供认证信息。
- 示例:
Authorization: Bearer
- 示例:
-
Cookie:包含客户端存储在浏览器中的 cookie 信息。
- 示例:
Cookie: sessionId=abc123
- 示例:
示例:
- GET /index.html HTTP/1.1
- Host: www.example.com
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
- Accept: text/html, application/json
3. 请求体(Request Body)
请求体是可选的,主要用于 POST
、PUT
、PATCH
等请求方法,用于传输要发送给服务器的实际数据。通常,HTTP 请求体包含要上传的数据,如表单提交的数据、文件、JSON 数据等。
作用:
- 传递数据:请求体主要用来传递客户端提交的数据,这些数据会被服务器接收并处理。比如,用户注册时填写的表单内容,或者在上传文件时,文件的内容也会包含在请求体中。
- 传输格式:请求体的数据可以有不同的格式,常见的包括:
application/x-www-form-urlencoded
:用于传统的 HTML 表单提交,数据以key=value
的形式传输。application/json
:用于传输 JSON 格式的数据,适用于 Web API。multipart/form-data
:用于文件上传时,数据被分为多个部分发送。text/plain
:纯文本数据。
示例(以 POST
请求为例):
- POST /submit HTTP/1.1
- Host: www.example.com
- Content-Type: application/json
- Content-Length: 41
-
- {
- "username": "john_doe",
- "password": "securepassword"
- }
在这个例子中,请求体包含了一个 JSON 对象,里面传输了用户名和密码。
总结:
- 请求行:定义了 HTTP 请求的基本信息,包括请求方法、请求资源和协议版本。
- 请求头:包含了额外的信息,如客户端环境、支持的响应格式、身份验证信息等,用来协助服务器处理请求。
- 请求体:用于传输客户端要发送给服务器的实际数据,通常与
POST
、PUT
等方法一起使用。
这三部分共同构成了一个完整的 HTTP 请求,服务器根据这些信息来处理客户端请求并生成相应的响应
评论记录:
回复评论: