需求分析:
1.需要Linux c 网络编程基础,
2.需要了解 http 协议
3.需要天气信息相关api(可以从阿里云上购买,很便宜的!)
4.需要cJSON解析库(因为获取到的天气信息一般是用cJSON
封装,有的是用xml封装则需要相关解析库)
cJSON下载链接:https://github.com/DaveGamble/cJSON
cJSON在线代码格式化:http://tool.oschina.net/codeformat/json
cJSON简解及使用:
cJSON核心结构体:
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
} cJSON;
说明:cJSON数据是以(键-值)形式存在。每个键对应的值都可以
访问(valuestring、valueint、valuedouble)成员得到。
主要用到的函数:
1. CSJON_PUBLIC(cJSON*) cJSON_Parse(const char *value);
用了获得根节点,
2. CSJON_PUBLIC(cJSON*) cJSON_GetObjectItem(const cJSON* const object, const char *const string);
用来获得根节点下的子节点,
3. CSJON_PUBLIC(void) cJSON_Delete(const cJSON *item);
用来释放为根节点分配的内存!
获取天气的http协议:
"GET /phone-post-code-weeather?"
"phone_code=021 "
"HTTP/1.1\r\n"
"Host:ali-weather.showapi.com\r\n"
"Authorization:APPCODE xxxxxx\r\n\r\n"
解释说明:
"/phone-post-code-weeather"此部分对应于 path格式
"Host:ali-weather.showapi.com"此部分对应于 接口域名
"phone_code" 表示城市编号021为上海(记住后面要空格)
"xxxxxx" 为你购买的APPCODE 这我就不填。。。
![这里写图片描述](http://img.blog.csdn.net/20170815164731926?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ29taW5nRmx5aW5n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
相关代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "common.h"
#include "cJSON.h"
#define SERV_PORT 80
typedef struct sockaddr SA;
void http_request(char *buf, int size, char *city_name);
void analyze_CJSON(const char *json);
char *recv_msg(int sockfd);
int main(int argc, char **argv)
{
int sockfd;
struct hostent *hptr = NULL;
struct sockaddr_in servaddr;
struct in_addr **pptr;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
err_quit("socket error");
}
char *alias_name = "ali-weather.showapi.com";
if ((hptr = gethostbyname(alias_name)) == NULL) {
err_quit("gethostbyname error for host: %s: %s",
alias_name, hstrerror(h_errno));
}
pptr = (struct in_addr **)hptr->h_addr_list;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0) {
err_quit("connect error");
}
char buf[MAXLINE];
char *phone_code = "021";
http_request(buf, MAXLINE, phone_code);
if (write(sockfd, buf, strlen(buf)) != strlen(buf)) {
err_quit("write error");
}
char *json = recv_msg(sockfd);
analyze_CJSON(json);
return EXIT_SUCCESS;
}
void http_request(char *buf, int size, char *phone_code)
{
bzero(buf, size);
snprintf(buf, size, "GET /phone-post-code-weeather?"
"phone_code=%s "
"HTTP/1.1\r\n"
"Host:ali-weather.showapi.com\r\n"
"Authorization:APPCODE d487d937315848af80710a06f4592fee\r\n\r\n"
, phone_code);
}
char * recv_msg(int sockfd)
{
int nread;
char recvbuf[4096];
char *begin = NULL, *end = NULL;
char *lenght = NULL;
char *data = NULL;
char tar[] = "Content-Length: ";
bool flage = true;
while (1) {
bzero(recvbuf, sizeof(recvbuf));
if ((nread = read(sockfd, recvbuf, sizeof(recvbuf))) == 0) {
break;
}
if (strstr(recvbuf, "403") != NULL || strstr(recvbuf, "Quota Exhausted")) {
err_quit("your appcode is expire..");
}
if (flage) {
if ((begin = strstr(recvbuf, tar)) != NULL) {
if ((end = strstr(begin, "\r\n")) != NULL) {
lenght = malloc(end - (begin+strlen(tar)));
memcpy(lenght, begin+strlen(tar), end-(begin+strlen(tar)));
data = calloc(1, atoi(lenght));
if (data == NULL) {
err_quit("malloc error");
}
strcpy(data, strrchr(recvbuf, '\n')+1);
}
} else {
continue;
}
}
if (!flage) {
strcat(data, recvbuf);
}
if (strlen(data) == atoi(lenght)) {
break;
}
flage = false;
}
printf("atoi(lenght) = %d\n", atoi(lenght));
free(lenght);
return data;
}
void analyze_CJSON(const char *json)
{
cJSON *root = cJSON_Parse(json);
if (root == NULL) {
err_quit("cJSON_Parse error");
}
cJSON *body = cJSON_GetObjectItem(root, "showapi_res_body");
if (body == NULL) {
err_quit("body error");
}
if (cJSON_GetObjectItem(body, "ret_code")->valueint == -1) {
err_quit("json data invalid..");
}
cJSON *now = cJSON_GetObjectItem(body, "now");
if (now == NULL) {
err_quit("get now failure");
}
cJSON *aqiDetai = cJSON_GetObjectItem(now, "aqiDetail");
if (aqiDetai == NULL) {
err_quit("get aqiDetai failure");
}
cJSON *cityinfo = cJSON_GetObjectItem(body, "cityInfo");
if (cityinfo == NULL) {
err_quit("get cityinfo failure");
}
cJSON *f1 = cJSON_GetObjectItem(body, "f1");
if (f1 == NULL) {
err_quit("get f1 failure");
}
cJSON *f2 = cJSON_GetObjectItem(body, "f2");
if (f1 == NULL) {
err_quit("get f2 failure");
}
cJSON *f3 = cJSON_GetObjectItem(body, "f3");
if (f1 == NULL) {
err_quit("get f3 failure");
}
printf(" country:\t%s\n", cJSON_GetObjectItem(cityinfo, "c9")->valuestring);
printf(" area:\t%s\n", cJSON_GetObjectItem(aqiDetai, "area")->valuestring);
printf(" quality:\t%s\n", cJSON_GetObjectItem(aqiDetai, "quality")->valuestring);
printf(" pm2_5:\t%s\n", cJSON_GetObjectItem(aqiDetai, "pm2_5")->valuestring);
printf(" pm10:\t%s\n", cJSON_GetObjectItem(aqiDetai, "pm10")->valuestring);
printf(" aqi:\t%s\n", cJSON_GetObjectItem(aqiDetai, "aqi")->valuestring);
printf("\ntoday weather:\n");
printf(" day_weather:\t%s\n", cJSON_GetObjectItem(f1, "day_weather")->valuestring);
printf(" day_wind_power:\t%s\n", cJSON_GetObjectItem(f1, "day_wind_power")->valuestring);
printf(" day_wind_direction:\t%s\n", cJSON_GetObjectItem(f1, "day_wind_direction")->valuestring);
printf("day_air_temperature:\t%s\n", cJSON_GetObjectItem(f1, "day_air_temperature")->valuestring);
printf("\ntomorrow weather:\n");
printf(" day_weather:\t%s\n", cJSON_GetObjectItem(f2, "day_weather")->valuestring);
printf(" day_wind_power:\t%s\n", cJSON_GetObjectItem(f2, "day_wind_power")->valuestring);
printf(" day_wind_direction:\t%s\n", cJSON_GetObjectItem(f2, "day_wind_direction")->valuestring);
printf("day_air_temperature:\t%s\n", cJSON_GetObjectItem(f2, "day_air_temperature")->valuestring);
printf("\nthe day after tomorrow weather:\n");
printf(" day_weather:\t%s\n", cJSON_GetObjectItem(f3, "day_weather")->valuestring);
printf(" day_wind_power:\t%s\n", cJSON_GetObjectItem(f3, "day_wind_power")->valuestring);
printf(" day_wind_direction:\t%s\n", cJSON_GetObjectItem(f3, "day_wind_direction")->valuestring);
printf("day_air_temperature:\t%s\n", cJSON_GetObjectItem(f3, "day_air_temperature")->valuestring);
cJSON_Delete(root);
}