-
Notifications
You must be signed in to change notification settings - Fork 21
/
httpclient_sample.c
148 lines (128 loc) · 4.28 KB
/
httpclient_sample.c
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* File : httpclient.c
*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-07-20 flybreak first version
* 2018-09-05 flybreak Upgrade API to webclient latest version
*/
#include <webclient.h> /* 使用 HTTP 协议与服务器通信需要包含此头文件 */
#include <sys/socket.h> /* 使用BSD socket,需要包含socket.h头文件 */
#include <netdb.h>
#include <cJSON.h>
#include <finsh.h>
#define GET_HEADER_BUFSZ 1024 //头部大小
#define GET_RESP_BUFSZ 1024 //响应缓冲区大小
#define GET_URL_LEN_MAX 256 //网址最大长度
#define GET_URI "http://mobile.weather.com.cn/data/sk/%s.html" //获取天气的 API
#define AREA_ID "101021300" //上海浦东地区 ID
/* 天气数据解析 */
void weather_data_parse(rt_uint8_t *data)
{
cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
root = cJSON_Parse((const char *)data);
if (!root)
{
rt_kprintf("No memory for cJSON root!\n");
return;
}
object = cJSON_GetObjectItem(root, "sk_info");
item = cJSON_GetObjectItem(object, "cityName");
rt_kprintf("\ncityName:%s ", item->valuestring);
item = cJSON_GetObjectItem(object, "temp");
rt_kprintf("\ntemp :%s ", item->valuestring);
item = cJSON_GetObjectItem(object, "wd");
rt_kprintf("\nwd :%s ", item->valuestring);
item = cJSON_GetObjectItem(object, "ws");
rt_kprintf("\nws :%s ", item->valuestring);
item = cJSON_GetObjectItem(object, "sd");
rt_kprintf("\nsd :%s ", item->valuestring);
item = cJSON_GetObjectItem(object, "date");
rt_kprintf("\ndate :%s", item->valuestring);
item = cJSON_GetObjectItem(object, "time");
rt_kprintf("\ntime :%s \n", item->valuestring);
if (root != RT_NULL)
cJSON_Delete(root);
}
void weather(int argc, char **argv)
{
rt_uint8_t *buffer = RT_NULL;
int resp_status;
struct webclient_session *session = RT_NULL;
char *weather_url = RT_NULL;
int content_length = -1, bytes_read = 0;
int content_pos = 0;
/* 为 weather_url 分配空间 */
weather_url = rt_calloc(1, GET_URL_LEN_MAX);
if (weather_url == RT_NULL)
{
rt_kprintf("No memory for weather_url!\n");
goto __exit;
}
/* 拼接 GET 网址 */
rt_snprintf(weather_url, GET_URL_LEN_MAX, GET_URI, AREA_ID);
/* 创建会话并且设置响应的大小 */
session = webclient_session_create(GET_HEADER_BUFSZ);
if (session == RT_NULL)
{
rt_kprintf("No memory for get header!\n");
goto __exit;
}
/* 发送 GET 请求使用默认的头部 */
if ((resp_status = webclient_get(session, weather_url)) != 200)
{
rt_kprintf("webclient GET request failed, response(%d) error.\n", resp_status);
goto __exit;
}
/* 分配用于存放接收数据的缓冲 */
buffer = rt_calloc(1, GET_RESP_BUFSZ);
if (buffer == RT_NULL)
{
rt_kprintf("No memory for data receive buffer!\n");
goto __exit;
}
content_length = webclient_content_length_get(session);
if (content_length < 0)
{
/* 返回的数据是分块传输的. */
do
{
bytes_read = webclient_read(session, buffer, GET_RESP_BUFSZ);
if (bytes_read <= 0)
{
break;
}
}while (1);
}
else
{
do
{
bytes_read = webclient_read(session, buffer,
content_length - content_pos > GET_RESP_BUFSZ ?
GET_RESP_BUFSZ : content_length - content_pos);
if (bytes_read <= 0)
{
break;
}
content_pos += bytes_read;
}while (content_pos < content_length);
}
/* 天气数据解析 */
weather_data_parse(buffer);
__exit:
/* 释放网址空间 */
if (weather_url != RT_NULL)
rt_free(weather_url);
/* 关闭会话 */
if (session != RT_NULL)
webclient_close(session);
/* 释放缓冲区空间 */
if (buffer != RT_NULL)
rt_free(buffer);
}
MSH_CMD_EXPORT(weather, Get weather by webclient);