日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【ESP8266】NONOS SDK开发,发送HTTP请求

發(fā)布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【ESP8266】NONOS SDK开发,发送HTTP请求 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

網(wǎng)絡(luò)方面不是很懂,可能描述有一點不準(zhǔn)確。

主要是通過ESP8266,在NONOS-SDK環(huán)境下,用URL地址,發(fā)出HTTP請求,接收并處理信息。


假設(shè)已經(jīng)大致了解廠家提供的SDK,以及Eclipse開發(fā)環(huán)境如何使用,現(xiàn)在大致要做的是以下幾步:

1、連上WiFi(連上網(wǎng)絡(luò))

2、與URL地址的服務(wù)器建立TCP連接

3、發(fā)出HTTP請求

4、接收并處理信息


現(xiàn)在就開始一步步地講:

一、連上WiFi

連上WiFi這里我采用比較笨的方式,就是固定的WiFi和密碼,直接連上就是了

需要用到幾個函數(shù):

1234567891011 bool wifi_set_opmode (uint8 opmode); //設(shè)置ESP8266模式,選擇station模式wifi_station_set_config(&stationConf); //設(shè)置連接WiFi的參數(shù)//有結(jié)構(gòu)體:struct station_config {uint8 ssid[32]; //ssiduint8 password[64]; //密碼uint8 bssid_set;uint8 bssid[6];};bool wifi_station_connect (void); //連接WiFiuint8 wifi_station_get_connect_status (void); //獲取連接狀態(tài)
?來自CODE的代碼片 wifi_func

1)設(shè)置ESP8266 的工作模式;

2)設(shè)置好WiFi的SSID和密碼;

3)開始連接WiFi;

4)檢查WiFi連接狀態(tài),若為5則連接成功。

1234567891011121314151617181920212223242526272829303132333435363738394041 void init_CollectWifi(){ uint8 wifistatus; struct station_config stationConf; os_memcpy(&stationConf.ssid,WIFI_SSID,32); //輸入路由器賬號 os_memcpy(&stationConf.password,WIFI_PWD,64); //輸入路由器密碼 //stationConf.bssid_set = 0; wifi_station_set_config(&stationConf);//設(shè)置wifi_station的接口,并保存到flash。#ifdef DEBUG os_printf("\r\n call connect_wifi\n"); os_printf("wifi name: %s\n",stationConf.ssid); os_printf("wifi pw:%s\n",stationConf.password); os_printf("wifi connecting..\n");#endif if (wifi_station_connect()) {#ifdef DEBUG os_printf("wifi_station_connect = true\n");#endif } else {#ifdef DEBUG os_printf("wifi_station_connect = flase\n");#endif } //os_delay_us(2000000); wifistatus = wifi_station_get_connect_status();#ifdef DEBUG os_printf("wifi connect status = %d\n",wifistatus); os_printf("wifi status = %s\n", Word_Status[wifistatus]);#endif}
?來自CODE的代碼片 init_collectwifi.c

在開始初始化的時候應(yīng)該還要有一句?wifi_set_opmode(STATION_MODE);


二、建立TCP連接

這里又分為幾步:

1)解析URL,獲取域名

要建立TCP連接,首先應(yīng)該獲取服務(wù)器的域名。

舉個例子:https://code.csdn.net/snippets_manage

那么域名就應(yīng)該是code.csdn.net,我們要建立連接也是與這個服務(wù)器建立連接,所以我們需要把URL地址拆開

123456789101112131415161718192021222324252627282930 void ICACHE_FLASH_ATTR http_parse_request_url(char *URL,char *host,char *filename,unsigned short *port){ char *PA; char *PB; memset(host,0,sizeof(host)); memset(filename,0,sizeof(filename)); *port=0; if(!(*URL)) return; PA=URL; if(!strncmp(PA,"http://",strlen("http://"))) PA=URL+strlen("http://"); if(!strncmp(PA,"https://",strlen("https://"))) PA=URL+strlen("https://"); PB=strchr(PA,'/'); if(PB){ memcpy(host,PA,strlen(PA)-strlen(PB)); if(PB+1){ memcpy(filename,PB+1,strlen(PB-1)); filename[strlen(PB)-1]=0; } host[strlen(PA)-strlen(PB)]=0; }else{ memcpy(host,PA,strlen(PA)); host[strlen(PA)]=0; } PA=strchr(host,':'); if(PA) *port=atoi(PA+1); else *port=80;}
?來自CODE的代碼片 http_parse_request_url.c

2)解析域名,轉(zhuǎn)換成IP地址


這里,當(dāng)它找到對應(yīng)的IP地址后,會有調(diào)用回調(diào)函數(shù),我們可以在回調(diào)函數(shù)中進行TCP連接

我是這樣調(diào)用這個函數(shù)的:espconn_gethostbyname(&user_tcp_conn,host, &addr,user_esp_dns_found);


3)TCP連接

123456 //DNS回調(diào)函數(shù)void ICACHE_FLASH_ATTR user_esp_dns_found(const char *name, ip_addr_t *ipaddr, void *arg){ struct ip_info info; wifi_get_ip_info(STATION_IF,&info); iot_station_init(ipaddr,&info.ip,port);}
?來自CODE的代碼片 dns_cb.c


獲得了IP地址后就可以連接了

12345678910111213141516171819202122232425262728293031 /** 函數(shù)名: iot_station_init* 描述: 以ESP8266為客戶端,建立tcp連接* 輸入: remote_ip:服務(wù)器IP* local_ip:本地IP* remote_port:服務(wù)器端口* 返回: true:成功* 調(diào)用: 無*/bool ICACHE_FLASH_ATTR iot_station_init(struct ip_addr *remote_ip ,struct ip_addr *local_ip ,int remote_port ){#ifdef DEBUGos_printf("\r\ncall iot_station_init\n");#endifuser_tcp_conn.type = ESPCONN_TCP;user_tcp_conn.state = ESPCONN_NONE;user_tcp_conn.proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));os_memcpy(user_tcp_conn.proto.tcp->local_ip ,local_ip,4);os_memcpy(user_tcp_conn.proto.tcp->remote_ip ,remote_ip,4);user_tcp_conn.proto.tcp->local_port = espconn_port();user_tcp_conn.proto.tcp->remote_port = remote_port;espconn_regist_connectcb(&user_tcp_conn ,user_tcp_connect_cb);espconn_regist_reconcb(&user_tcp_conn ,user_tcp_recon_cb);#ifdef DEBUGos_printf("espconn_connect\n");#endifespconn_connect(&user_tcp_conn);return true;}
?來自CODE的代碼片 iot_station_init



三、發(fā)送HTTP請求

在(二)中的函數(shù)應(yīng)該是在要發(fā)出命令時一氣呵成的,所以這里我們應(yīng)該封裝好一個接口函數(shù),

只要用戶給出URL和發(fā)送的命令時,系統(tǒng)就能自動完成功能。

123456789101112131415161718 void ICACHE_FLASH_ATTR HttpReadFile(char *URL,char *method,char *postdata){struct ip_addr addr;memset(buffer,0,1024);#ifdef DEBUGos_printf("\r\nThe URL request:\n%s\n", URL);#endifhttp_parse_request_url(URL,host,filename,&port);if(strcmp(method,"GET")==0){os_sprintf(buffer,GET,filename,host);}else{os_sprintf(buffer,POST,filename,strlen(postdata),host,postdata);}espconn_gethostbyname(&user_tcp_conn,host, &addr,user_esp_dns_found);}
?來自CODE的代碼片 HttpReadFile

這里有包含頭文件 my_client.h ,里面定義了GET和POST的格式

12345678910111213141516171819202122 #ifndef APP_INCLUDE_MY_CLIENT_H_#define APP_INCLUDE_MY_CLIENT_H_#include "user_main.h"#include "espconn.h"#include "mem.h"char buffer[1024];#define GET "GET /%s HTTP/1.1\r\nAccept: */*\r\nHost: %s\r\nConnection: Keep-Alive\r\n\r\n"#define POST "POST /%s HTTP/1.1\r\nAccept: */*\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: %s\r\nConnection: Keep-Alive\r\n\r\n%s"struct espconn user_tcp_conn;//工作模式初始化,傳三個參:遠端IP,本地IP,遠端端口。bool iot_station_init(struct ip_addr *remote_ip ,struct ip_addr *local_ip ,int remote_port );void user_tcp_connect_cb(void *arg);void user_tcp_reconnect_cb(void *arg ,sint8 err); //連接失敗時會執(zhí)行這個函數(shù),可以在本回調(diào)函數(shù)中進行重連。void user_tcp_recv_cb(void *arg ,char *pdata ,unsigned short len); //注冊成功接收網(wǎng)絡(luò)數(shù)據(jù)的回調(diào)函數(shù)void user_tcp_sent_cb(void *arg); //注冊網(wǎng)絡(luò)數(shù)據(jù)發(fā)送成功的回調(diào)函數(shù)void user_tcp_discon_cb(void *arg); //注冊 TCP 連接正常斷開成功的回調(diào)函數(shù)#endif /* APP_INCLUDE_MY_CLIENT_H_ */
?來自CODE的代碼片 my_client.h


四、接收信息

在之前一直沒有講,在建立了TCP連接后有四個很重要的回調(diào)函數(shù)要聲明。

就是上面my_client.h中的四個回調(diào)函數(shù)

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 /** 函數(shù)名: user_tcp_sent_cb* 描述: tcp發(fā)送成功后的回調(diào)函數(shù)* 輸入: arg:tcp連接句柄* 返回: 無* 調(diào)用: 無*/void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg){#ifdef DEBUGos_printf("\r\nsend success!");#endif}/** 函數(shù)名: user_tcp_discon_cb* 描述: tcp連接斷開后的回調(diào)函數(shù)* 輸入: arg:tcp連接句柄* 返回: 無* 調(diào)用: 無*/void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg){#ifdef DEBUGos_printf("\r\ndisconnect success!");#endif}/** 函數(shù)名: user_tcp_recv_cb* 描述: tcp接收成功后的回調(diào)函數(shù)* 輸入: arg:tcp連接句柄* pdata:收到數(shù)據(jù)* len:收到數(shù)據(jù)長度* 返回: 無* 調(diào)用: 無*/void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg, char *pdata, unsigned short len){ }/** 函數(shù)名: user_tcp_recon_cb* 描述: tcp重連成功后的回調(diào)函數(shù)* 輸入: arg:tcp連接句柄* err:錯誤碼* 返回: 無* 調(diào)用: 無*/void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err){#ifdef DEBUGos_printf("connect err,errno:%d\r\n",err);#endifespconn_connect((struct espconn *)arg);}/** 函數(shù)名: user_tcp_connect_cb* 描述: tcp連接成功后的回調(diào)函數(shù),需要再注冊一些回調(diào)函數(shù)* 輸入: arg:tcp連接句柄* 返回: 無* 調(diào)用: 無*/void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg){struct espconn *pespconn=arg;#ifdef DEBUGos_printf("\r\nconnect success!");#endif }
?來自CODE的代碼片 tcp_cb

收到信號后的處理,我們就寫在recv_cb里面就可以了

但是有一點要注意的是:我們使用的這個NONOS_SDK,它是有看門狗的,當(dāng)回調(diào)函數(shù)執(zhí)行時間過長是會導(dǎo)致重啟的!

參考資料: HTTP和URL介紹?http://www.cnblogs.com/LDSmallCat/p/4942039.html ESP8266 SDK 編程手冊.pdf 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的【ESP8266】NONOS SDK开发,发送HTTP请求的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。