ESP8266学习进阶协议类(1)——http请求

HTTP简介

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。

HTTP工作原理

HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。

Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。

Web服务器根据接收到的请求后,向客户端发送响应信息。

HTTP默认端口号为80,但是你也可以改为8080或者其他端口。

HTTP三点注意事项:

  • **HTTP是无连接:**无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
  • **HTTP是媒体独立的:**这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。
  • **HTTP是无状态:**HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。

具体实现过程

  • 通常要使用HTTP请求都是先建立起TCP/IP的连接,与服务器建立TCP通信;
  • 发送具体的HTTP请求
  • 接收服务器返回的数据
  • 关闭连接

当然在ESP8266上实现还需要先让设备能够联网上网,ESP8266-RTOS-SDK提供了对应的wifi连接接口,见 esp_wifi.h 所有的wifi相关接口都在这里,包括切换STA和AP,在ESP8266-RTOS-SDK中,提供了一个适配器的概念,目的是在TCPIP堆栈上提供一个抽象层,据官方文档介绍是为了实现切换到其他TCPIP栈而设计的,具体的我也没研究透,根据文档,只需要在连接wifi前对适配器进行初始化就行;

tcpip_adapter_init();

连接wifi:

**WiFi初始化:esp_err_t esp_wifi_init(const wifi_init_config_t *config) **

例如WiFi控制结构,RX / TX缓冲区,WiFi NVS结构等,此WiFi也会启动WiFi任务。

相关参数结构体:wifi_init_config_t 针对wifi配置的相关结构体

typedef struct {
    system_event_handler_t event_handler;          /**< WiFi event handler */
    void*                  osi_funcs;              /**< WiFi OS functions */
    int                    static_rx_buf_num;      /**< WiFi static RX buffer number */
    int                    dynamic_rx_buf_num;     /**< WiFi dynamic RX buffer number */
    int                    tx_buf_type;            /**< WiFi TX buffer type */
    int                    static_tx_buf_num;      /**< WiFi static TX buffer number */
    int                    dynamic_tx_buf_num;     /**< WiFi dynamic TX buffer number */
    int                    csi_enable;             /**< WiFi channel state information enable flag */
    int                    ampdu_rx_enable;        /**< WiFi AMPDU RX feature enable flag */
    int                    ampdu_tx_enable;        /**< WiFi AMPDU TX feature enable flag */
    int                    nvs_enable;             /**< WiFi NVS flash enable flag */
    int                    nano_enable;            /**< Nano option for printf/scan family enable flag */
    int                    tx_ba_win;              /**< WiFi Block Ack TX window size */
    int                    rx_ba_win;              /**< WiFi Block Ack RX window size */
    int                    magic;                  /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;

第一次看到这个头都大,所幸官方提供了一个默认的宏配置:

#define WIFI_INIT_CONFIG_DEFAULT() { \
    .event_handler = &esp_event_send, \
    .osi_funcs = NULL, \
    .static_rx_buf_num = 5,\
    .dynamic_rx_buf_num = 0,\
    .tx_buf_type = 0,\
    .static_tx_buf_num = 6,\
    .dynamic_tx_buf_num = 0,\
    .csi_enable = 0,\
    .ampdu_rx_enable = 0,\
    .ampdu_tx_enable = 0,\
    .nvs_enable = 1,\
    .nano_enable = 0,\
    .tx_ba_win = 0,\
    .rx_ba_win = 0,\
    .magic = WIFI_INIT_CONFIG_MAGIC\
};

esp_err_t esp_wifi_deinit( void )

与WiFi初始化相对于的一个函数,用于释放esp_wifi_init中分配的所有资源并停止WiFi任务。


esp_err_t esp_wifi_set_storage(wifi_storage_t storage )

设置WiFi API配置存储类型

typedef enum {
    WIFI_STORAGE_FLASH,  /**< 所有配置信息都保存在memory和flash中 */
    WIFI_STORAGE_RAM,    /**< 所有配置信息只保存在memory中 */
} wifi_storage_t;

esp_err_t esp_wifi_set_mode(wifi_mode_t mode);

设置wifi工作模式;

typedef enum {
    WIFI_MODE_NULL = 0,  /**< null mode */
    WIFI_MODE_STA,       /**< WiFi station mode */
    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
    WIFI_MODE_MAX
} wifi_mode_t;

*esp_err_t esp_wifi_set_config(wifi_interface_t , wifi_config_t conf);

设置ESP8266 STA或AP的配置

参数类型 解析
wifi_interface_t typedef enum {
ESP_IF_WIFI_STA = 0, /< ESP8266 station interface */
ESP_IF_WIFI_AP, /
< ESP8266 soft-AP interface */
ESP_IF_MAX
} esp_interface_t;
wifi_config_t typedef union {
wifi_ap_config_t ap; /< configuration of AP */
wifi_sta_config_t sta; /
< configuration of STA */
} wifi_config_t;

由于wifi_config_t是一个联合体,在使用的时候我们可以这样,例如使用STA模式:

wifi_config_t wifi_config = {           	//填入wifi信息
        .sta = {                            //sta模式
            .ssid = EXAMPLE_WIFI_SSID,		//作为STA需要接入的AP(路由器/WIFI)的ID
            .password = EXAMPLE_WIFI_PASS,	//(路由器/WIFI)密码
        },
    };

esp_err_t esp_wifi_start(void);

当所有的配置都做好后,调用该函数会根据当前配置启动WiFi如果模式为WIFI_MODE_STA,则创建站点控制块并启动站点如果模式为WIFI_MODE_AP,则创建软AP控制块并启动soft-AP如果模式为WIFI_MODE_APSTA,则创建软AP和站点控制块并启动软AP和工作站。

让8266在STA模式连接WIFI步骤总结如下:

  • 初始化适配器
  • 新建一个配置wifi的结构体,然后调用wifi初始化函数
  • 设置WiFi API配置存储类型
  • 设置WiFi工作模式
  • 设置ESP8266 STA或AP的配置
  • 启动WiFi
	tcpip_adapter_init();
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);
    esp_wifi_set_storage(WIFI_STORAGE_RAM);
    wifi_config_t wifi_config = {           //填入wifi信息
        .sta = {                            //sta模式
            .ssid = EXAMPLE_WIFI_SSID,	    //wifi名称
            .password = EXAMPLE_WIFI_PASS,  //wifi密码
        },
    };
    esp_wifi_set_mode(WIFI_MODE_STA);
   	esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
    esp_wifi_start();

发出http请求

完成前面的联网后,发出http请求就很简单了,

  • 创建一个TCP的客户端socket
  • 往socket写入具体的HTTP请求
  • 接收回发的数据
    本文使用的是我之前封装好的一个接口,点击获取,如果对你有用请点个关注或者星标,谢谢

头文件:#include <sys/socket.h>

int socket(int domain, int type, int protocol); 		//创建socket
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); //连接服务器

完了之后就是往socket写入封装好的URL即可

头文件:#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);	 //写
ssize_t read(int fd, void *buf, size_t count);			//读

本次测试使用的是青云客智能聊天机器人API免费的API,本来是测试获取天气的,但是不知道为什么获取的天气数据中文没法输出,就换成了翻译功能;

#define HEAD_FORMAT "GET /api.php?key=free&appid=0&msg=翻译武汉加油 HTTP/1.1\r\nHost:api.qingyunke.com\r\n\r\n"

效果如图:(天气左边是8266串口输出的,只能显示数字和英文,右边是纯代码测试的输出)

ESP8266学习进阶协议类(1)——http请求

ESP8266学习进阶协议类(1)——http请求
工程源码见我的Github


我的GITHUB

我的个人博客

CSDN

上一篇:【ESP32】【ESP32-Vaquita-DSPG 开发板及配套 ESP AVS for AWS IoT SDK 发布】


下一篇:ESP32 阿里云 入门学习②