使用ESP32S3在Arduino框架下通过TCP方式利用浏览器登录网页进行通信与操作

官方示例说明

/*
    创建了一个WiFi接入点,并在其上提供了一个web服务器。
    
    步骤:
    1. 连接到接入点“yourAp”
    2. 将您的web浏览器指向http://192.168.4.1/H打开LED或http://192.168.4.1/L关闭它
    或
    在PuTTY终端上以192.168.4.1为IP地址,80为端口,运行raw TCP“GET /H”和“GET /L”
*/

#include <WiFi.h>
#include <WiFiAP.h>

#define LED_BUILTIN 12   // 设置连接测试LED的GPIO引脚,如果开发板有内置LED,则注释此行

//设置这些为您想要的凭据
const char *ssid = "yourAP";
const char *password = "yourPassword";
IPAddress apIP(192, 168, 4, 1);            //设置AP的IP地址
WiFiServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

//如果要开放AP,可以去掉password参数。
//密码长度必须大于7位
  if (!WiFi.softAP(ssid, password)) {
    log_e("Soft AP creation failed.");
    while(1);
  }
  WiFi.softAPConfig( apIP, apIP, IPAddress(255, 255, 255, 0));
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();

  Serial.println("Server started");
}

void loop() {
  WiFiClient client = server.available();   // 监听接入的客户端

  if (client) {                             // 如果接入一个客户端,
    Serial.println("New Client.");           // 则在串口打印一条提示信息
    String currentLine = "";                // 创建一个字符串来保存来自客户端的传入数据
    while (client.connected()) {            // 在客户端连接时循环
      if (client.available()) {             // 如果要从客户端读取字节,
        char c = client.read();             // 读取一个字节,然后
        Serial.write(c);                    // 在串行监视器上打印出来
        if (c == '\n') {                    // 如果字节是换行字符

          // 如果当前行为空,则一行中有两个换行符。
          // 这是客户端HTTP请求的结束,所以发送一个响应:
          if (currentLine.length() == 0) {
            // HTTP报头总是以状态行开头(例如HTTP/1.1 200 OK)
            // 还有一个content-type,这样客户端就知道接下来会发生什么,然后是一个空行:
            client.println("HTTP/1.1 200 OK");        //状态行
            client.println("Content-type:text/html"); //响应头
            client.println();

            // HTTP响应的内容在报头后面:                //响应体
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // HTTP响应以另一个空行结束:
            client.println();
            // 跳出while循环:
            break;
          } else {    // 如果你有一个换行符,那么清除currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // 如果你有除了回车符以外的任何字符,
          currentLine += c;      // 将它添加到currentLine的末尾
        }

        // 检查客户端请求是“GET /H”还是“GET /L”:
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H打开LED
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);                // GET /L关闭LED
        }
      }
    }
    // 关闭连接:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

代码实现的目标与实现过程

目标:

创建了一个WiFi接入点,并在其上提供了一个web服务器。

用户操作:

1. 连接到接入点“yourAp”

2. 将您的web浏览器指向http://192.168.4.1/H打开LED或http://192.168.4.1/L关闭它或在PuTTY终端上以192.168.4.1为IP地址,80为端口,运行raw TCP“GET /H”和“GET /L”

过程:

  1. 创建一个热点,设置esp地址为192.168.4.1,端口80

  2. 创建服务器

  3. 等待客户端接入

  4. 客户端接入后,循环遍历客户端是否发来消息

  5. 若发来消息,则读取信息,并将每次读取到的信息保存到字符变量‘c’中

  以下为重点,请务必仔细阅读

  1. 只要‘c’接收到的信息不是空行,则说明esp服务器还没有完整收到客户端的http请求。因此将每次收到的数据加入到字符串变量currentLine的末尾,并检查是否以“GET /H”还是“GET /L”为结尾,若对得上则执行相应的控制动作。

        这与HTTP请求的格式和协议有关。在常见的HTTP协议中,HTTP请求由三部分组成:请求行请求头请求体

        请求行中包含了请求的方法(例如GET、POST)、路径(URL)和协议版本(例如HTTP/1.1)。

        请求头包含了额外的元数据信息,如请求的主机、内容类型、Accept-Encoding等。

        请求体包含了可选的请求数据,主要用于POST请求发送数据给服务器。


        在这段代码中,我们主要关注了请求行部分。当一个HTTP请求结束时,会有两个连续的换行符(\n\n)出现,表示请求行之后没有额外的请求头和请求体的内容。

        因此,如果当前行为空(即 currentLine.length() == 0),那么我们可以认为这是一个空行,表示请求的头部结束,没有请求体,因此可以断定整个请求结束了。这时服务器可以发送对应的HTTP响应。

        需要注意的是,这段代码并没有处理请求头和请求体的内容,它只关注了请求的路径部分,根据不同的路径进行LED的控制。


        以下为这段代码收到的一个http请求示例

GET /H HTTP/1.1
Host: 192.168.4.1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 11; RMX3161 Build/RKQ1.201217.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.16 SearchCraft/3.9.1 (Baidu; P1 11)​
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
dnt: 1
X-Requested-With: mark.via
  1. 判断http请求接收完成后,需要对这个请求进行回应,按照标准的http响应格式,

        一个HTTP响应由三部分组成:状态行、响应头响应体

        状态行包含了响应的状态码和对应的状态消息,例如HTTP/1.1 200 OK表示请求成功。

        响应头包含了额外的元数据信息,如响应的内容类型、长度、缓存控制等。

        响应体包含了实际的响应数据,如HTML内容、文件等。

        在Arduino的代码中,client.println("xxx")这一行是用来发送响应体数据的,而在这个特定的代码中,因为响应体为空,所以只发送了一个空行。

        根据HTTP协议的规范,一个HTTP响应以两个连续的换行符来表示响应头的结束,也就是空行。这是因为响应头和响应体之间需要有一个空行来分隔。

        因此,在这个代码片段中,client.println()这一行的作用是发送一个空行,表示响应头的结束,然后服务器不再发送其他响应体内容。这样就完成了一个空的HTTP响应。

        这个空行的目的是满足HTTP协议中响应的格式要求,确保正确解析和处理响应。

对用到的一些函数和类进行说明:

WiFi.softAP(ssid, password)

WiFi.softAPIP()

WiFiServer server(80)

创建侦听指定端口上的传入连接的服务器。

参数:端口:要侦听的端口 (INT)

无返回值

server.begin()

告知服务器开始侦听传入连接

无参无返回值

server.available()

无参

返回值:客户端对象; 如果没有客户端有可供读取的数据,则此对象将在 if 语句中计算为 false

server.write()

将数据写入连接到服务器的所有客户端。

参数:

数据:要写入的值(字节或字符)

返回:

字节 :写入的字节数。没有必要阅读此内容。

WiFiClient client

创建一个客户端,该客户端可以连接到 client.connect() 中定义的指定互联网 IP 地址和端口。

无参无返回值

client.connected()

客户端是否已连接。请注意,如果连接已关闭但仍有未读数据,则认为客户端已连接。

无参

返回值:如果客户端已连接,则返回 true,如果未连接,则返回 false。

client.available()

返回可供读取的字节数(即,它所连接的服务器已写入客户端的数据量)。

available() 继承自 Stream 实用程序类。

无参

返回值:可用字节数。

client.read()

读取从客户端连接到的服务器收到的下一个字节(在最后一次调用 read() 之后)。

无参

返回值:下一个字节(或字符),如果没有可用,则为 -1。

client.println()

将数据打印到客户端连接到的服务器,后跟回车符和换行符。将数字打印为数字序列,每个数字都是 ASCII 字符(例如,数字 123 作为三个字符“1”、“2”、“3”发送)。

参数:

数据(可选):要打印的数据(字符、字节、整数、长整型或字符串)

BASE(可选):用于打印数字的基数:DEC 表示十进制(以 10 为基数),OCT 表示八进制(以 8 为基数),十六进制表示十六进制(以 16 为基数)。

返回值:

byte:返回写入的字节数,尽管读取该数字是可选的

client.print()

将数据打印到客户端连接到的服务器。将数字打印为数字序列,每个数字都是 ASCII 字符(例如,数字 123 作为三个字符“1”、“2”、“3”发送)。

参数:

数据:要打印的数据(字符、字节、整数、长整型或字符串)

BASE(可选):用于打印数字的基数:,DEC 表示十进制(以 10 为基数),OCT 表示八进制(以 8 为基数),十六进制表示十六进制(以 16 为基数)。

返回值:

字节 :返回写入的字节数,尽管读取该数字是可选的

client.stop()

断开与服务器的连接

无参无返回值

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
您可以通过以下步骤将温湿度数据通过TCP协议上传到巴法云平台: 1. 首先,在Arduino IDE中安装ESP32开发板支持库。在"工具"菜单中选择"开发板",然后选择"ESP32 Dev Module"。 2. 在Arduino IDE中,打开一个新的Sketch,并导入所需的库文件。您需要导入以下库文件: ```cpp #include <WiFi.h> #include <WiFiClient.h> ``` 3. 设置您的WiFi网络连接。在代码中,使用`WiFi.begin()`函数连接到您的WiFi网络,如下所示: ```cpp const char* ssid = "Your_SSID"; const char* password = "Your_PASSWORD"; void setup() { WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); } ``` 请将`Your_SSID`替换为您的WiFi网络名称(SSID),将`Your_PASSWORD`替换为您的WiFi密码。 4. 创建TCP连接到巴法云平台。使用`WiFiClient`类创建一个TCP客户端对象,并使用`client.connect()`函数连接到巴法云平台的服务器。确保替换`your_bafa_server.com`和`your_bafa_port`为正确的服务器地址和端口号。 ```cpp const char* server = "your_bafa_server.com"; const int port = your_bafa_port; void loop() { if (client.connect(server, port)) { Serial.println("Connected to server"); // 在此处添加上传温湿度数据的代码 } else { Serial.println("Connection failed"); } client.stop(); delay(5000); } ``` 5. 在`client.connect()`成功连接到服务器后,您可以在相应的代码位置添加上传温湿度数据的代码。例如,您可以使用`client.print()`函数将数据发送到服务器。 ```cpp float temperature = 25.5; float humidity = 50.0; client.print("POST /upload_data HTTP/1.1\r\n"); client.print("Host: your_bafa_server.com\r\n"); client.print("Content-Type: application/json\r\n"); client.print("Content-Length: "); client.print(15 + sizeof(temperature) + sizeof(humidity)); client.print("\r\n\r\n"); client.print("{\"temperature\":"); client.print(temperature); client.print(",\"humidity\":"); client.print(humidity); client.println("}"); ``` 请根据您的需求修改上传数据的格式和内容。 6. 在完成数据上传后,使用`client.stop()`函数关闭TCP连接,并在适当的位置添加延迟以控制上传频率。 ```cpp client.stop(); delay(5000); // 5秒的延迟,用于控制上传频率 ``` 以上是将温湿度数据通过TCP协议上传到巴法云平台的基本步骤。请根据巴法云平台的具体要求和接口文档进行进一步的开发和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幻酌

爸爸真帅!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值