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

网络方面不是很懂,可能描述有一点不准确。

主要是通过ESP8266,在NONOS-SDK环境下,用URL地址,发出HTTP请求,接收并处理信息。


假设已经大致了解厂家提供的SDK,以及Eclipse开发环境如何使用,现在大致要做的是以下几步:

1、连上WiFi(连上网络)

2、与URL地址的服务器建立TCP连接

3、发出HTTP请求

4、接收并处理信息


现在就开始一步步地讲:

一、连上WiFi

连上WiFi这里我采用比较笨的方式,就是固定的WiFi和密码,直接连上就是了

需要用到几个函数:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
           
           
bool wifi_set_opmode (uint8 opmode); //设置ESP8266模式,选择station模式
wifi_station_set_config(&stationConf); //设置连接WiFi的参数
//有结构体:
struct station_config {
uint8 ssid[32]; //ssid
uint8 password[64]; //密码
uint8 bssid_set;
uint8 bssid[6];
};
bool wifi_station_connect (void); //连接WiFi
uint8 wifi_station_get_connect_status (void); //获取连接状态
 来自CODE的代码片
wifi_func

1)设置ESP8266 的工作模式;

2)设置好WiFi的SSID和密码;

3)开始连接WiFi;

4)检查WiFi连接状态,若为5则连接成功。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
            
            
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 ); //设置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

在开始初始化的时候应该还要有一句 wifi_set_opmode(STATION_MODE);


二、建立TCP连接

这里又分为几步:

1)解析URL,获取域名

要建立TCP连接,首先应该获取服务器的域名。

举个例子:https://code.csdn.net/snippets_manage

那么域名就应该是code.csdn.net,我们要建立连接也是与这个服务器建立连接,所以我们需要把URL地址拆开

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
            
            
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)解析域名,转换成IP地址


这里,当它找到对应的IP地址后,会有调用回调函数,我们可以在回调函数中进行TCP连接

我是这样调用这个函数的:espconn_gethostbyname(&user_tcp_conn,host, &addr,user_esp_dns_found);


3)TCP连接

 1
 2
 3
 4
 5
 6
            
            
//DNS回调函数
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地址后就可以连接了

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
            
            
/*
* 函数名: iot_station_init
* 描述: 以ESP8266为客户端,建立tcp连接
* 输入: remote_ip:服务器IP
* local_ip:本地IP
* remote_port:服务器端口
* 返回: true:成功
* 调用: 无
*/
bool ICACHE_FLASH_ATTR iot_station_init(struct ip_addr *remote_ip ,struct ip_addr *local_ip ,int remote_port )
{
#ifdef DEBUG
os_printf("\r\ncall iot_station_init\n");
#endif
user_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 DEBUG
os_printf("espconn_connect\n");
#endif
espconn_connect(&user_tcp_conn);
return true;
}
 来自CODE的代码片
iot_station_init



三、发送HTTP请求

在(二)中的函数应该是在要发出命令时一气呵成的,所以这里我们应该封装好一个接口函数,

只要用户给出URL和发送的命令时,系统就能自动完成功能。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
             
             
void ICACHE_FLASH_ATTR HttpReadFile(char *URL,char *method,char *postdata)
{
struct ip_addr addr;
memset(buffer,0,1024);
#ifdef DEBUG
os_printf("\r\nThe URL request:\n%s\n", URL);
#endif
http_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的格式

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
             
             
#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 ); //连接失败时会执行这个函数,可以在本回调函数中进行重连。
void user_tcp_recv_cb ( void * arg , char * pdata , unsigned short len ); //注册成功接收网络数据的回调函数
void user_tcp_sent_cb ( void * arg ); //注册网络数据发送成功的回调函数
void user_tcp_discon_cb ( void * arg ); //注册 TCP 连接正常断开成功的回调函数
#endif /* APP_INCLUDE_MY_CLIENT_H_ */
 来自CODE的代码片
my_client.h


四、接收信息

在之前一直没有讲,在建立了TCP连接后有四个很重要的回调函数要声明。

就是上面my_client.h中的四个回调函数

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
             
             
/*
* 函数名: user_tcp_sent_cb
* 描述: tcp发送成功后的回调函数
* 输入: arg:tcp连接句柄
* 返回: 无
* 调用: 无
*/
void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg)
{
#ifdef DEBUG
os_printf("\r\nsend success!");
#endif
}
/*
* 函数名: user_tcp_discon_cb
* 描述: tcp连接断开后的回调函数
* 输入: arg:tcp连接句柄
* 返回: 无
* 调用: 无
*/
void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg)
{
#ifdef DEBUG
os_printf("\r\ndisconnect success!");
#endif
}
/*
* 函数名: user_tcp_recv_cb
* 描述: tcp接收成功后的回调函数
* 输入: arg:tcp连接句柄
* pdata:收到数据
* len:收到数据长度
* 返回: 无
* 调用: 无
*/
void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg, char *pdata, unsigned short len)
{
}
/*
* 函数名: user_tcp_recon_cb
* 描述: tcp重连成功后的回调函数
* 输入: arg:tcp连接句柄
* err:错误码
* 返回: 无
* 调用: 无
*/
void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err)
{
#ifdef DEBUG
os_printf("connect err,errno:%d\r\n",err);
#endif
espconn_connect((struct espconn *)arg);
}
/*
* 函数名: user_tcp_connect_cb
* 描述: tcp连接成功后的回调函数,需要再注册一些回调函数
* 输入: arg:tcp连接句柄
* 返回: 无
* 调用: 无
*/
void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg)
{
struct espconn *pespconn=arg;
#ifdef DEBUG
os_printf("\r\nconnect success!");
#endif
}
 来自CODE的代码片
tcp_cb

收到信号后的处理,我们就写在recv_cb里面就可以了

但是有一点要注意的是:我们使用的这个NONOS_SDK,它是 有看门狗的,当回调函数执行时间过长是会导致重启的!

参考资料:
HTTP和URL介绍 http://www.cnblogs.com/LDSmallCat/p/4942039.html
ESP8266 SDK 编程手册.pdf
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值