本文将以苏宁免费的时间接口为例: http://quan.suning.com/getSysTime.do 演示如何向服务器的API接口发送GET请求报文,而且解析数据。
GET请求格式
具体GET请求的过程我不作多余解释,以避免有错误误导读者,如想了解能够搜索一下请求头内容以及解释。 咱们在链接服务器成功后能够向服务器发送如下内容,就能够得到相应的结果。
GET http://quan.suning.com/getSysTime.do HTTP/1.1
Host: quan.suning.com
//结尾须要有一个空行而且回车换行,也就是说要有两个换行回车
实际上GET请求所有内容有九行,这里只要发送请求的资源名称以及使用的协议版?和?请求的服务器地址?就能够了。浏览器
使用TCP助手测试
咱们先用TCP助手链接服务器,并发送请求测试一下,以保证这个方案确实可行。
查看API接口的服务器地址和端口号
由于TCP助手的局限,咱们链接时必须先知道API接口的服务器地址和端口号。可是正式使用时候就没必要要了,直接使用域名就能够链接。 简单的查看地址的方法有不少,在这里博主介绍使用浏览器方法(测试IE浏览器好像不行,我是用的是QQ浏览器)。 1.直接在浏览器地址栏输入苏宁时间接口的URL,就会看到返回的数据内容(是一串json数据) 2.点击键盘F12,选择Network页签,而后刷新网页,便可看到Name下有两个文件
3.点击第一个文件便可查看详情。里面包含了整个过程收发的内容。能够看到请求的URL,请求方式,和请求的地址(你看到的可能和个人不同,均可以使用)
网络
使用TCP助手链接
打开TCP调试助手而后输入地址和端口号,点击链接网络便可
至此,咱们的准备工做就完成了。
使用TCP助手发送GET请求报文
下面将我前文说到的报文黏贴进去(请注意格式),点击发送按钮很快就会收到服务器发送回来的数据。
数据包含响应报文和消息体。 第一行为状态行:200 OK 便是请求成功 空行后面紧接着的就是消息体,内容应该与浏览器显示的结果一致。
若是返回结果有问题,多数是由于复制的问题。删除干净后,输入请求报文内容至发送区。 至此,咱们使用TCP调试助手测试成功。
链接服务器并发送GET请求
若是你已经实现链接服务器,而且能收发数据,难么直接使用发送数据命令将请求报文发送出去就能够了。
下面展现具体实现代码:
//头文件中宏定义内容
//时间地址和服务器
#define ESP_TIME_TCP_ADDRESS "quan.suning.com"
#define ESP_TIME_TCP_POINT "80"
//GET请求报文
#define ESP_TIME_INFO "GET http://quan.suning.com/getSysTime.do HTTP/1.1\r\nHost: quan.suning.com\r\n\r\n"
//开启透传模式后,直接经过串口向ESP8266发送报文
USART_Send_String(USART2, ESP_TIME_INFO); //发送GET请求报文,得到返回结果
while(!(ESP_RX_STATE > 0)); //判断接收标志
/*
此处写收到结果后作的解析处理
*/
ESP_RX_STATE --;//解析数据置位
如此下来,咱们发送了GET请求而且还能接受到返回的结果,是否是超简单。那么如何处理结果呢?
解析返回结果
咱们收到的数据格式为json格式,这是一种普遍使用数据交换格式。
解析数据
由于咱们的数据格式很是固定,我能够针对这个格式进行解析。再来回看下接收到的内容: {“sysTime2”:“2019-11-02 22:38:52”,“sysTime1”:“20191102223852”} 使用了两种时间表示方法,均可以使用。从"sysTime1"后的第三位开始就是咱们须要的结果,所以我只要使用函数 strstr()函数定位到"sysTime1"的位置日后移动11位(strstr函数返回的是查找的字符串的首地址)就能够了。
data_pt = strstr((const char *) ESP_RX_BUF.buf,(const char *)"sysTime1"); //寻找到时间结果的地址,首地址返回给字符类型的指针变量(char*) data_pt
年的首地址移动11位;
year_string = data_pt + YERA_ADD_DRES; //年份地址
月份首地址移动15位; 日期首地址移动17位; 小时首地址移动19位; 分钟首地址移动21位; 秒钟首地址移动23位; 以此类推能够获得每一个数据的位置(其实直接能够当一个字符串处理)。
处理数据
咱们实际上是获得了字符串类型的时间数据,已经能够直接使用了。为了方便运算继续进行数据转换,以便其余位置的使用。
得到年:
//得到年函数(由于以年开始的字符串长度过长,因此使用不一样的方法)
//输入值是年位置的地址
//返回值是 整型的10进制四位数
int Get_Year(char *y)
{
int year_return;
char *year_temp;
char year[5] = {
0};
char i;
//年的获取须要提取一次字符串,不然没法读取
year_temp = y;
for(i = 0; i<4; i++)
{
year[i] = *year_temp;
year_temp ++;
}
year_return = atoi(&year[0]);
return year_return;
}
得到月份:
//得到月份函数
//输入值是月份位置的地址
//返回值是 整型的10进制两位数
int Get_Moonth(char *m)
{
int moonth_return;
moonth_return = atoi(m)/100000000; //取月份
return moonth_return;
}
得到日期
//得到日期函数
//输入值是日期位置的地址
//返回值是 整型的10进制两位数
int Get_Day(char *d)
{
int day_return;
day_return = atoi(d)/1000000; //取日期
return day_return;
}
得到时间
//得到时间
//输入值是时间的位置的地址
//返回值是 整型的10进制的时间总秒数
int Get_Times(char *h, char *m, char *s)
{
int time_return;
int hour_return;
int min_return;
int sec_return;
hour_return = atoi(h)/10000; //取小时
min_return = atoi(m)/100; //取分钟
sec_return = atoi(s); //取秒数
time_return = hour_return*3600 + min_return*60 + sec_return; //转换成总秒数
return time_return;
}
完整解析过程
个人整个处理时间的代码以下:
//定义时间存储的全局变量(也能够定义成结构体)
__IO uint32_t TIMES = 0;
__IO uint32_t YEARS = 2019;
__IO uint32_t MOONS = 1;
__IO uint32_t DAYS = 1;
__IO uint32_t WEEKS = 0;
//获取网络时间并解析给系统
void GET_Net_Time(void)
{
char *data_pt;
char *day_string;
char *moon_string;
char *year_string;
char *hour_string;
char *minute_string;
char *second_string;
RT_Send_String(USART2, ESP_TIME_INFO); //发送GET请求
while(!(ESP_RX_STATE > 0)); //判断接收标志
data_pt = strstr((const char *) ESP_RX_BUF.buf,(const char *)"sysTime1"); //寻找到时间结果的地址
ESP_RX_STATE --;
if(data_pt != NULL)
{
day_string = data_pt + DAYS_ADD_DRES; //日期地址
moon_string = data_pt + MOON_ADD_DRES; //月份地址
year_string = data_pt + YERA_ADD_DRES; //年份地址
hour_string = data_pt + HOURS_ADD_DRES; //小时地址
minute_string = data_pt + MINUTES_ADD_DRES; //分钟地址
second_string = data_pt + SECONDS_ADD_DRES; //秒中地址
//将时间信息传递给全局变量
DAYS = Get_Day(day_string);
MOONS = Get_Moonth(moon_string);
YEARS = Get_Year(year_string);
TIMES = Get_Times(hour_string, minute_string, second_string);
}
else
{
printf("get net time failed!\r\n");
}
}
//得到年函数(以年开始的字符串长度过长,因此使用不一样的方法)
//输入值是年位置的地址
//返回值是 整型的10进制四位数
int Get_Year(char *y)
{
int year_return;
char *year_temp;
char year[5] = {
0};
char i;
//年的获取须要提取一次字符串,不然没法读取
year_temp = y;
for(i = 0; i<4; i++)
{
year[i] = *year_temp;
year_temp ++;
}
year_return = atoi(&year[0]);
return year_return;
}
//得到月份函数
//输入值是月份位置的地址
//返回值是 整型的10进制两位数
int Get_Moonth(char *m)
{
int moonth_return;
moonth_return = atoi(m)/100000000; //取月份
return moonth_return;
}
//得到日期函数
//输入值是日期位置的地址
//返回值是 整型的10进制两位数
int Get_Day(char *d)
{
int day_return;
day_return = atoi(d)/1000000; //取日期
return day_return;
}
//得到时间
//输入值是时间的位置的地址
//返回值是 整型的10进制的时间总秒数
int Get_Times(char *h, char *m, char *s)
{
int time_return;
int hour_return;
int min_return;
int sec_return;
hour_return = atoi(h)/10000; //取小时
min_return = atoi(m)/100; //取分钟
sec_return = atoi(s); //取秒数
time_return = hour_return*3600 + min_return*60 + sec_return; //转换成总秒数
return time_return;
}
如此,全部的数据解析完毕,剩下的就是使用啦,具体怎么显示根据本身的方法实现。
|