Bootstrap

【史上最全面ESP32教程】http通信


前言

随着物联网(IoT)的快速发展,ESP32作为一款高性能、低功耗的Wi-Fi和蓝牙双模芯片,受到了广泛的关注和应用。在物联网设备中,HTTP协议是实现设备与服务器之间通信的常用协议。本文将介绍HTTP协议的基本概念及其常见应用场景。


HTTP协议是什么?

HTTP(HyperText Transfer Protocol,超文本传输协议)是一种用于传输超文本的应用层协议。它是万维网(WWW)的基础,定义了客户端(如浏览器)与服务器之间的通信规则。HTTP协议采用请求-响应模式,客户端发送请求,服务器返回响应。

HTTP协议的特点

  • 无状态:每次请求都是独立的,服务器不会保留之前请求的状态。
  • 灵活性:支持多种数据格式,如HTML、JSON、XML等。
  • 简单性:易于实现和使用,广泛应用于Web开发。

HTTP协议的常见应用

  • Web浏览:浏览器通过HTTP协议请求网页内容,服务器返回HTML页面。
  • API通信:物联网设备通过HTTP协议与服务器进行数据交互,如上传传感器数据或获取控制指令。
  • 文件传输:通过HTTP协议下载或上传文件,如软件更新或日志文件。

esp32 使用http通信

通信流程

  1. 连接网络
  2. 开始http通信
  3. 发送请求并获取响应
  4. 关闭连接

基础使用

我们需要使用HTTPClient类来进行通信
如果我们要开启一个http通信使用下面这个函数,参数为你要http通信的url:

bool begin(String url);

如果我们要GET一个内容,我们可以使用下面这个函数:

int GET();

他的返回值为状态码。
状态码有下面这些取值:

  • 200 OK:请求成功。具体的含义取决于HTTP方法。例如,GET方法表示资源已被获取并在消息体中传输。
  • 201 Created:请求成功,并且新的资源已经作为结果创建。这通常是在POST请求或某些PUT请求后发送的响应。
  • 204 No Content:没有要发送的内容,但头部可能有用。用户代理可能会使用新的头部更新此资源的缓存头部。
  • 301 Moved Permanently:请求的URL已永久移动到新位置,并且将来的引用应使用新的URL。
  • 400 Bad Request:服务器无法理解请求的语法。
  • 401 Unauthorized:请求需要用户验证。
  • 403 Forbidden:服务器理解请求,但拒绝执行它。
  • 404 Not Found:服务器找不到请求的资源。
  • 500 Internal Server Error:服务器遇到错误,无法完成请求

我们可以通过下面这个函数来获取GET的返回值:

String getString(void);

我们可以使用下面这个函数来关闭http连接:

void end(void);
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = ".......";        // WiFi网络名称
const char* password = ".......";  // WiFi网络密码

void setup() {
  Serial.begin(115200);  // 初始化串口通信
  
  // 连接到WiFi网络
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");

  // 设置HTTPClient对象
  HTTPClient http;
  
  // 为GET请求设置目标URL
  String url = "http://example.com/api/data"; // 替换为你的目标URL
  
  // 发送GET请求
  http.begin(url);
  
  // 发送请求并获取响应
  int httpResponseCode = http.GET();
  
  if (httpResponseCode > 0) { // 如果收到响应
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode); // 打印响应代码
    
    String payload = http.getString(); // 获取响应内容
    Serial.println(payload); // 打印响应内容
  } else {
    Serial.print("Error code: ");
    Serial.println(httpResponseCode); // 打印错误代码
  }
  
  http.end(); // 关闭连接
}

void loop() {
  // 程序主循环,此处不需要添加其他代码
}

HTTPClient 常用的函数

函数介绍:

void end(void);
  • 函数原型: void end(void);
  • 函数作用: 关闭HTTPClient对象,释放资源。
  • 函数参数: 无。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    // 处理响应
    http.end(); // 关闭HTTP连接
    
bool connected(void);
  • 函数原型: bool connected(void);
  • 函数作用: 检查HTTPClient对象是否已连接到服务器。
  • 函数参数: 无。
  • 返回值的作用: 返回true表示连接成功,返回false表示未连接或连接已断开。
  • 示例代码:
    HTTPClient http;
    if (http.connected()) {
      // 执行请求操作
    } else {
      // 重新连接或处理断开连接情况
    }
    
void setReuse(bool reuse);
  • 函数原型: void setReuse(bool reuse);
  • 函数作用: 设置是否启用HTTP keep-alive功能,允许多次复用同一TCP连接。
  • 函数参数:
    • reuse:布尔值,true表示启用keep-alive,false表示禁用。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.setReuse(true); // 启用keep-alive
    
void setUserAgent(const String& userAgent);
  • 函数原型: void setUserAgent(const String& userAgent);
  • 函数作用: 设置HTTP请求的用户代理(User-Agent)标头。
  • 函数参数:
    • userAgent:String类型,要设置的用户代理字符串。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.setUserAgent("ESP32 Client");
    
void setAuthorization(const char * user, const char * password);
  • 函数原型: void setAuthorization(const char * user, const char * password);
  • 函数作用: 设置基本身份验证的用户名和密码。
  • 函数参数:
    • user:用户名字符串。
    • password:密码字符串。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.setAuthorization("username", "password");
    
int GET();
  • 函数原型: int GET();
  • 函数作用: 发送HTTP GET请求并接收响应。
  • 函数参数: 无。
  • 返回值的作用: 返回HTTP响应状态代码(例如200表示成功)。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    // 处理响应
    
String getString(void);
  • 函数原型: String getString(void);
  • 函数作用: 获取HTTP响应的正文内容。
  • 函数参数: 无。
  • 返回值的作用: 返回包含HTTP响应正文内容的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    if (httpResponseCode > 0) {
      String response = http.getString();
      Serial.println(response);
    }
    
int PATCH(uint8_t * payload, size_t size);
  • 函数原型: int PATCH(uint8_t * payload, size_t size);
  • 函数作用: 发送HTTP PATCH请求并附带数据。
  • 函数参数:
    • payload:指向要发送数据的字节数组的指针。
    • size:要发送数据的大小(字节数)。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    uint8_t data[] = { 0x01, 0x02, 0x03 };
    int httpResponseCode = http.PATCH(data, sizeof(data));
    
int PATCH(String payload);
  • 函数原型: int PATCH(String payload);
  • 函数作用: 发送HTTP PATCH请求并附带数据(字符串形式)。
  • 函数参数:
    • payload:要发送的数据字符串。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    String data = "key=value";
    int httpResponseCode = http.PATCH(data);
    
int POST(uint8_t * payload, size_t size);
  • 函数原型: int POST(uint8_t * payload, size_t size);
  • 函数作用: 发送HTTP POST请求并附带数据。
  • 函数参数:
    • payload:指向要发送数据的字节数组的指针。
    • size:要发送数据的大小(字节数)。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    uint8_t data[] = { 0x01, 0x02, 0x03 };
    int httpResponseCode = http.POST(data, sizeof(data));
    
int POST(String payload);
  • 函数原型: int POST(String payload);
  • 函数作用: 发送HTTP POST请求并附带数据(字符串形式)。
  • 函数参数:
    • payload:要发送的数据字符串。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    String data = "key=value";
    int httpResponseCode = http.POST(data);
    
int PUT(uint8_t * payload, size_t size);
  • 函数原型: int PUT(uint8_t * payload, size_t size);
  • 函数作用: 发送HTTP PUT请求并附带数据。
  • 函数参数:
    • payload:指向要发送数据的字节数组的指针。
    • size:要发送数据的大小(字节数)。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    uint8_t data[] = { 0x01, 0x02, 0x03 };
    int httpResponseCode = http.PUT(data, sizeof(data));
    
int PUT(String payload);
  • 函数原型: int PUT(String payload);
  • 函数作用: 发送HTTP PUT请求并附带数据(字符串形式)。
  • 函数参数:
    • payload:要发送的数据字符串。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    String data = "key=value";
    int httpResponseCode = http.PUT(data);
    
int sendRequest(const char * type, String payload);
  • 函数原型: int sendRequest(const char * type, String payload);
  • 函数作用: 发送自定义类型的HTTP请求,并附带数据(字符串形式)。
  • 函数参数:
    • type:HTTP请求类型,例如 “GET”, “POST”, “PUT” 等。
    • payload:要发送的数据字符串。
  • 返回值的作用: 返回HTTP响应状态代码。
  • 示例代码:
    HTTPClient http;
    int httpResponseCode = http.sendRequest("POST", "key=value");
    
void addHeader(const String& name, const String& value, bool first = false, bool replace = true);
  • 函数原型: void addHeader(const String& name, const String& value, bool first = false, bool replace = true);
  • 函数作用: 添加HTTP请求头。
  • 函数参数:
    • name:头部字段的名称。
    • value:头部字段的值。
    • first:可选参数,默认为false。如果为true,则将新头部添加到头部列表的开头。
    • replace:可选参数,默认为true。如果为true,则替换现有的同名头部;如果为false,则添加到现有同名头部后面。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.addHeader("Content-Type", "application/json");
    
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
  • 函数原型: void collectHeaders(const char* headerKeys[], const size_t headerKeysCount);
  • 函数作用: 指定要收集的HTTP响应头。
  • 函数参数:
    • headerKeys:指向包含要收集的头部字段名称的数组。
    • headerKeysCount:数组中头部字段名称的数量。
  • 返回值的作用: 无返回值。
  • 示例代码:
    const char* headersToCollect[] = { "Content-Length", "Content-Type" };
    HTTPClient http;
    http.collectHeaders(headersToCollect, sizeof(headersToCollect) / sizeof(headersToCollect[0]));
    
String header(const char* name);
  • 函数原型: String header(const char* name);
  • 函数作用: 获取指定名称的HTTP响应头值。
  • 函数参数:
    • name:要获取的头部字段名称。
  • 返回值的作用: 返回包含头部字段值的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    String contentType = http.header("Content-Type");
    
String header(size_t i);
  • 函数原型: String header(size_t i);
  • 函数作用: 获取指定索引位置的HTTP响应头值。
  • 函数参数:
    • i:要获取的头部字段的索引(从0开始)。
  • 返回值的作用: 返回包含头部字段值的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    String firstHeader = http.header(0);
    
String headerName(size_t i);
  • 函数原型: String headerName(size_t i);
  • 函数作用: 获取指定索引位置的HTTP响应头名称。
  • 函数参数:
    • i:要获取的头部字段的索引(从0开始)。
  • 返回值的作用: 返回包含头部字段名称的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    String firstName = http.headerName(0);
    
int headers();
  • 函数原型: int headers();
  • 函数作用: 获取HTTP响应中头部字段的数量。
  • 函数参数: 无。
  • 返回值的作用: 返回头部字段的数量。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    int numHeaders = http.headers();
    
bool hasHeader(const char* name);
  • 函数原型: bool hasHeader(const char* name);
  • 函数作用: 检查HTTP响应中是否存在指定名称的头部字段。
  • 函数参数:
    • name:要检查

的头部字段名称。

  • 返回值的作用: 如果存在指定名称的头部字段,则返回true;否则返回false
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    if (http.hasHeader("Content-Type")) {
      // 处理存在Content-Type头部的情况
    }
    
int getSize(void);
  • 函数原型: int getSize(void);
  • 函数作用: 获取HTTP响应正文的大小(字节数)。
  • 函数参数: 无。
  • 返回值的作用: 返回HTTP响应正文的大小。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    int contentSize = http.getSize();
    
const String &getLocation(void);
  • 函数原型: const String &getLocation(void);
  • 函数作用: 获取HTTP响应中的 Location 头部字段的值,用于处理重定向。
  • 函数参数: 无。
  • 返回值的作用: 返回包含 Location 头部字段值的String对象的引用。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    String redirectLocation = http.getLocation();
    
WiFiClient& getStream(void);
  • 函数原型: WiFiClient& getStream(void);
  • 函数作用: 获取底层的WiFiClient对象,用于直接访问底层网络连接。
  • 函数参数: 无。
  • 返回值的作用: 返回一个WiFiClient对象的引用。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    WiFiClient& stream = http.getStream();
    
WiFiClient* getStreamPtr(void);
  • 函数原型: WiFiClient* getStreamPtr(void);
  • 函数作用: 获取底层的WiFiClient对象指针,用于直接访问底层网络连接。
  • 函数参数: 无。
  • 返回值的作用: 返回一个指向WiFiClient对象的指针。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    WiFiClient* streamPtr = http.getStreamPtr();
    
int writeToStream(Stream* stream);
  • 函数原型: int writeToStream(Stream* stream);
  • 函数作用: 将HTTP响应内容写入给定的流(Stream)对象。
  • 函数参数:
    • stream:指向目标流对象的指针。
  • 返回值的作用: 返回写入流的字节数。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    WiFiClient client;
    int bytesWritten = http.writeToStream(&client);
    
String getString(void);
  • 函数原型: String getString(void);
  • 函数作用: 获取HTTP响应的正文内容。
  • 函数参数: 无。
  • 返回值的作用: 返回包含HTTP响应正文内容的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    String response = http.getString();
    
static String errorToString(int error);
  • 函数原型: static String errorToString(int error);
  • 函数作用: 将HTTPClient库中的错误代码转换为对应的错误消息字符串。
  • 函数参数:
    • error:HTTPClient库中定义的错误代码。
  • 返回值的作用: 返回表示错误消息的String对象。
  • 示例代码:
    HTTPClient http;
    http.begin("http://example.com/api/data");
    int httpResponseCode = http.GET();
    if (httpResponseCode < 0) {
      String errorMessage = HTTPClient::errorToString(httpResponseCode);
      Serial.println(errorMessage);
    }
    
void setCookieJar(CookieJar* cookieJar);
  • 函数原型: void setCookieJar(CookieJar* cookieJar);
  • 函数作用: 设置用于管理HTTP请求和响应中Cookie的CookieJar对象。
  • 函数参数:
    • cookieJar:指向CookieJar对象的指针。
  • 返回值的作用: 无返回值。
  • 示例代码:
    CookieJar cookieJar;
    HTTPClient http;
    http.setCookieJar(&cookieJar);
    
void resetCookieJar();
  • 函数原型: void resetCookieJar();
  • 函数作用: 重置CookieJar,清除所有保存的Cookie。
  • 函数参数: 无。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.resetCookieJar();
    
void clearAllCookies();
  • 函数原型: void clearAllCookies();
  • 函数作用: 清除所有保存的Cookie,无论它们是否过期。
  • 函数参数: 无。
  • 返回值的作用: 无返回值。
  • 示例代码:
    HTTPClient http;
    http.clearAllCookies();
    

总结

本文简要介绍了HTTP协议的基本概念及其在物联网设备中的常见应用。HTTP协议作为一种简单、灵活的通信协议,广泛应用于Web开发和物联网设备中。希望本文能帮助读者更好地理解HTTP协议及其在ESP32中的应用。

;