ESP8266例程解析②PostAndGet

函数逻辑
设置串口速率
设置wifi模式
设置连接WiFi信息
连接路由器
启动定时器函数
检测状态
解析HTTP网址

返回数据
每隔一段时间启动定时器 更新数据
执行调用函数时须关闭定时器

user_main.c

#include "driver/uart.h"
#include "user_main.h"

os_timer_t checkTimer_wifistate;

void Check_WifiState(void) {
	uint8 getState;
	getState = wifi_station_get_connect_status();

	//如果状态正确,证明已经成功连接到路由器
	if (getState == STATION_GOT_IP) {
		os_printf("WIFI连接成功!");
		os_timer_disarm(&checkTimer_wifistate); //取消定时器定时
		os_timer_disarm(&connect_timer);

		uint8 status = wifi_station_get_connect_status();
		if (status == STATION_GOT_IP) {
			uart0_sendStr("WIFI连接成功!");
			startHttpQuestByGET(
					"https://api.seniverse.com/v3/weather/now.json?key=your_api_key&location=beijing&language=zh-Hans&unit=c");
			return;
		}
	}

}
void user_init() {

	uart_init(57600, 57600);
	wifi_set_opmode(0x01); //设置为STATION模式
	struct station_config stationConf;
	os_strcpy(stationConf.ssid, "IAmYourFather");	  //改成你自己的   路由器的用户名
	os_strcpy(stationConf.password, "666666666"); //改成你自己的   路由器的密码
	wifi_station_set_config(&stationConf); //设置WiFi station接口配置,并保存到 flash
	wifi_station_connect(); //连接路由器

	os_timer_disarm(&checkTimer_wifistate); //取消定时器定时
	os_timer_setfn(&checkTimer_wifistate, (os_timer_func_t *) Check_WifiState,
	NULL); //设置定时器回调函数
	os_timer_arm(&checkTimer_wifistate, 500, true); //启动定时器,单位:毫秒
	os_printf("57600 end... \n\r");
}
void user_rf_pre_init() 
{
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
示例:

void ICACHE_FLASH_ATTR

user_set_station_config(void)

{

    char ssid[32] = SSID; 
    
    char password[64] = PASSWORD; 
    
    struct station_config stationConf; 
    
    stationConf.bssid_set = 0; //need not check MAC address of AP
    
    os_memcpy(&stationConf.ssid, ssid, 32); 
    
    os_memcpy(&stationConf.password, password, 64); 
    
    wifi_station_set_config(&stationConf);
}
void user_init(void)

{

    wifi_set_opmode(STATIONAP_MODE); //Set softAP + station mode
    user_set_station_config();
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

my_http.c

#include "my_http.h"
#include "c_types.h"
#include "client.h"
    
//剖析URL
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)){
		uart0_sendStr("\r\n ----- URL return -----  \r\n");
		return;
	}

	PA = URL;

	if (!strncmp(PA, "http://", strlen("http://")))  //字符串比较函数 1 2 比较3的位数  如果相等 执行
	 {
		PA = URL + strlen("http://");
	} 
	else if (!strncmp(PA, "https://", strlen("https://"))) 
   {
		PA = URL + strlen("https://");
	}

	PB = strchr(PA, '/');  //字符串1为一个字符串的指针,字符2为一个待查找字符 该函数返回在字符串 str 中第一次出现字符2 的位置,如果未找到该字符则返回 NULL。

	if (PB)
	 {
		uart0_sendStr("\r\n ----- PB=true -----  \r\n");
		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;

		uart0_sendStr(host,strlen(host));

	} 
	else
	 {
		uart0_sendStr("\r\n ----- PB=false -----  \r\n");
		memcpy(host, PA, strlen(PA));
		host[strlen(PA)] = 0;
		uart0_sendStr(host,strlen(host));
	}

	PA = strchr(host, ':');

	if (PA)
	{
		*port = atoi(PA + 1);
	}
   else
   {
		*port = 80;
	}
}

//寻找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);
	my_station_init(ipaddr, &info.ip, port);
}

//定义Get请求的实现
void ICACHE_FLASH_ATTR startHttpQuestByGET(char *URL)
{
	struct ip_addr addr;
	memset(buffer,0,1024);     //填充值  内存块指针 填充值 填充大小
	http_parse_request_url(URL,host,filename,&port); //HTTP解析
	os_sprintf(buffer,GET,filename,host);//注释见后面
	espconn_gethostbyname(&user_tcp_conn,host, &addr,
	user_esp_dns_found);//注释见后面
}


//定义Post请求的实现
void ICACHE_FLASH_ATTR startHttpQuestByPOST(char *URL,char *method,char *postdata)
{
	struct ip_addr addr;
	memset(buffer,0,1024);
	http_parse_request_url(URL,host,filename,&port);
	os_sprintf(buffer,POST,filename,strlen(postdata),host,postdata);
	espconn_gethostbyname(&user_tcp_conn,host, &addr,
	user_esp_dns_found);
}

原型
os_sprintf( char *buffer, const char *format, [ argument] … );
参数列表
buffer:char型指针,指向将要写入的字符串的缓冲区。
format:格式化字符串。
[argument]…:可选参数,可以是任何类型的数据。
返回值
返回写入buffer 的字符数,出错则返回-1. 如果 buffer 或 format 是空指针,且不出错而继续,函数将返回-1,并且 errno 会被设置为 EINVAL。
sprintf 返回以format为格式argument为内容组成的结果被写入buffer 的字节数,结束字符‘\0’不计入内。即,如果“Hello”被写入空间足够大的buffer后,函数sprintf 返回5。 [1]
同时buffer的内容将被改变。

/****************************************************************************

*FunctionName:espconn_gethostbyname

*描述:将主机名(字符串)解析为IP地址。

*参数:pespconn——espconn解析主机名

  • hostname——要查询的主机名

    扫描二维码关注公众号,回复: 4702324 查看本文章
  • addr——指向ip_addr_t的指针,如果

*它已经缓存在dns_table中(仅在ESPCONN_OK时有效)。

*返回!)

*.找到.——成功或失败时调用的回调函数

*或超时(仅当返回ERR_INPROGRESS时!)

*返回:err_t返回代码

*.–如果主机名是有效的IP地址字符串或主机,则ESPCONN_OK

*.name已经在本地名称表中。

*.–ESPCONN_INPROGRESS对要发送到DNS服务器的请求进行排队

*如果没有出现错误,则进行解析。

*-ESPCONN_ARG:dns客户端未初始化或主机名无效

*******************************************************************************/

err_t espconn_gethostbyname(struct espconnpespconn、const charhostname、ip_addr_t*addr、dns_find_callback.);

客户端
client.c

#include "client.h"
#include "iconv.h"
#include "stdio.h"
#include "string.h"

//成功接收到服务器返回数据函数
void ICACHE_FLASH_ATTR user_tcp_recv_cb(void *arg, char *pdata,
		unsigned short len) {
	uart0_sendStr("\r\n ----- 开始接受数据----- \r\n ");
	uart0_tx_buffer(pdata, strlen(pdata));
	uart0_sendStr("\r\n -----结束接受数据-----  \r\n ");

}

//发送数据到服务器成功的回调函数
void ICACHE_FLASH_ATTR user_tcp_sent_cb(void *arg) {
	uart0_sendStr("发送数据成功!\r\n ");
}

//断开服务器成功的回调函数
void ICACHE_FLASH_ATTR user_tcp_discon_cb(void *arg) {
	uart0_sendStr("断开连接成功!\r\n ");
}

//连接失败的回调函数,err为错误代码
void ICACHE_FLASH_ATTR user_tcp_recon_cb(void *arg, sint8 err) {
	uart0_sendStr("连接错误,错误代码为%d\r\n", err);
	espconn_connect((struct espconn *) arg);
}

//成功连接到服务器的回调函数
void ICACHE_FLASH_ATTR user_tcp_connect_cb(void *arg) {
	struct espconn *pespconn = arg;
	espconn_regist_recvcb(pespconn, user_tcp_recv_cb);
	espconn_regist_sentcb(pespconn, user_tcp_sent_cb);
	espconn_regist_disconcb(pespconn, user_tcp_discon_cb);

	uart0_sendStr("\r\n ----- 请求数据开始----- \r\n");
	uart0_tx_buffer(buffer, strlen(buffer));
	uart0_sendStr("\r\n -----请求数据结束-----  \r\n");

	espconn_sent(pespconn, buffer, strlen(buffer));

}
void ICACHE_FLASH_ATTR my_station_init(struct ip_addr *remote_ip,
		struct ip_addr *local_ip, int remote_port) {
	//配置
	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);  //连接失败的回调函数,err为错误代码
	//连接服务器
	espconn_connect(&user_tcp_conn);
}

猜你喜欢

转载自blog.csdn.net/qq_25205045/article/details/85252599