欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-06-29 08:58:25
...

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

相关标签: IoT入门到实战