iot-fan

联系: iotfan123#163.com
注意:
1,本博客之内容来源于网上收集以及相关技术人员提供,如果有侵犯到您的权益,请电邮我沟通;
2,本博客之内容乃分享,交流,学习,研究之目的,作者不对内容的真实性,有效性,及时性负责,也不对因本博客的任何内容导致的任何后果负责;
3,本博客之内容禁止转发到CSDN网站,转到别的网站请保留出处.

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

说明

  • 有不少网络API是通过http get或者post方式进行请求的,
  • 实际上这些api的请求往往都是相对固定的格式,而http是建立在tcp上的,我们往往只需要在TCP client的基础上,进行简单的模拟 即可实现这些API的访问
  • 本文以高德的天气API,基于ch32v208的tcp client例程,来实现实时天气的获取

实现

先获取api请求所用到的key

这里按照其网页文档来就行

模拟请求

用浏览器,或者curl之类的工具模拟请求我们的API:
下面我们用curl模拟请求合肥的实时天气

$ curl http://restapi.amap.com/v3/weather/weatherInfo\?city\=340100\&key\=<你申请的apikey>
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   255  100   255    0     0   1782      0 --:--:-- --:--:-- --:--:--  1795{"status":"1","count":"1","info":"OK","infocode":"10000","lives":[{"province":"安徽","city":"合肥市","adcode":"340100",
"weather":"晴","temperature":"8","winddirection":"东南","windpower":"≤3","humidity":"41","reporttime":"2022-12-30 13:04:50"}]}

对请求进行抓包分析

由于请求比较简单,我们简单的抓下http请求的数据,然后用芯片去模拟就行

构造tcp请求数据包

#define API_DOMAIN  "restapi.amap.com"                  /*DNS请求的API的域名*/
#define API_CITY    "340100"                            /*安徽合肥*/
#define API_KEY     "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  /*申请到的APIkey*/

const char header[] = \
            "GET /v3/weather/weatherInfo?city=%s&key=%s HTTP/1.1\r\n" \
            "Host: %s\r\n"\
            "User-Agent: curl/7.85.0\r\n"\
            "Accept: */*\r\n"\
            "\r\n";

char message[1024];
sprintf(message,header,API_CITY,API_KEY ,API_DOMAIN);
uint32_t send_len
send_len = strlen(message);

tcp建立后,进行请求

i = WCHNET_SocketSend(SocketId,message,&send_len);

tcp收到数据进行解析

这里我们拿到的是json数据,我们通过strstr比较简单的获取json的起始地址(判断收到的数据第一次出现{" 的位置)

    char *json_start = strstr((char *)SocketInf[id].RecvReadPoint,"{\"");
    if(json_start == NULL) {
        WCHNET_SocketRecv(id, NULL, &len);
        return ;
    }

然后使用cJSON 进行解析即可,注意cJSON的free和delete

    cJSON *arrayItem = cJSON_GetObjectItem(root,"status");
    out = cJSON_Print(arrayItem);
    //PRINT("%s\n",out);
    cJSON_free(out);

    arrayItem = cJSON_GetObjectItem(root,"info");
    out = cJSON_Print(arrayItem);
    //PRINT("%s\n",out);
    cJSON_free(out);

    arrayItem = cJSON_GetObjectItem(root,"infocode");
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);

    arrayItem = cJSON_GetObjectItem(root,"lives");
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);

    arrayItem = cJSON_GetArrayItem(arrayItem,0);
    out = cJSON_Print(arrayItem);
    PRINT("%s\n",out);
    cJSON_free(out);

    cJSON *item;
    item = cJSON_GetObjectItem(arrayItem,"province");
    out = cJSON_Print(item);
    PRINT("province:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"city");
    out = cJSON_Print(item);
    PRINT("city:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"adcode");
    out = cJSON_Print(item);
    PRINT("adcode:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"weather");
    out = cJSON_Print(item);
    PRINT("weather:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"temperature");
    out = cJSON_Print(item);
    PRINT("temperature:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"winddirection");
    out = cJSON_Print(item);
    PRINT("winddirection:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"windpower");
    out = cJSON_Print(item);
    PRINT("windpower:%s\n",out);
    cJSON_free(out);
    item = cJSON_GetObjectItem(arrayItem,"humidity");
    out = cJSON_Print(item);
    PRINT("humidity:%s\n",out);
    cJSON_free(out);

    item = cJSON_GetObjectItem(arrayItem,"reporttime");
    out = cJSON_Print(item);
    PRINT("reporttime:%s\n",out);
    cJSON_free(out);
    cJSON_Delete(root);

最终的结果

"10000"
[{
		"province":	"安徽",
		"city":	"���肥市",
		"adcode":	"340100",
		"weather":	"晴",
		"temperature":	"8",
		"winddirection":	"东南",
		"windpower":	"≤3",
		"humidity":	"40",
		"reporttime":	"2022-12-30 13:31:36"
	}]
{
	"province":	"安徽",
	"city":	"合肥市",
	"adcode":	"340100",
	"weather":	"晴",
	"temperature":	"8",
	"winddirection":	"东南",
	"windpower":	"≤3",
	"humidity":	"40",
	"reporttime":	"2022-12-30 13:31:36"
}
province:"安徽"
city:"合肥市"
adcode:"340100"
weather:"晴"
temperature:"8"
winddirection:"东南"
windpower:"≤3"
humidity:"40"
reporttime:"2022-12-30 13:31:36"
TCP Disconnect

附件

工程放到,ch32v20x evt>EXAM\ETH 下
把自己申请的apikey 替换掉
#define API_KEY "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" /*申请到的APIkey*/
串口打印在PA9,115200
https://gitee.com/iot-fan/iot-fan_at_cnblogs/tree/master/CH32V208/AN/ch32v208_http_get_amap_weather_api_test

posted on 2022-12-30 09:42  iot-fan  阅读(305)  评论(0编辑  收藏  举报