http協議獲取實時天氣並對包體進行json解析

北极甜虾哟發表於2024-06-12
/*************************************************************************************
*
*	@name    : main
*	@function: 該函式利用http協議獲取實時天氣,並對響應包體進行json解析。
*	@params  : none          
*	@retval  : int : 成功返回0 
* 	@date    : 2024/06/11
* 	@author  : 18312615416@163.com
* 	@version : V1.0		  
* 	@note    : 此函式運用心知天氣API
*
* ***********************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#include "cJSON.h"

#define  PORT  	80               //http協議埠
#define  IPADDR "116.62.81.138"  //心知天氣伺服器IP

#define  KEY    "xxxxxxxx"  //自己的私鑰
#define  LOCAL  "beijing"   //可修改

int main(int argc, char const *argv[])
{
	//1.建立TCP套接字
	int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (tcp_socket == -1)
	{
		fprintf(stderr, "tcp socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}

	
	//4.發起連線請求,等待接受伺服器接受連線
	struct sockaddr_in  dest_addr;
	dest_addr.sin_family 		= AF_INET; 						//協議族,是固定的
	dest_addr.sin_port   		= htons(PORT);					//伺服器埠,必須轉換為網路位元組序
	dest_addr.sin_addr.s_addr   = inet_addr(IPADDR);			//伺服器地址   


	int ret = connect(tcp_socket,(struct sockaddr *)&dest_addr,sizeof(dest_addr));
	if (ret < 0)
	{
		fprintf(stderr, "connect error,errno:%d,%s\n",errno,strerror(errno));
		exit(1);
	}


	//用於儲存HTTP的請求內容: 請求行 + 請求欄位 + \r\n + 請求包體(可選)  
	char reqbuf[1024] = {0};

	sprintf(reqbuf,"GET https://api.seniverse.com/v3/weather/now.json?key=%s&location=%s&language=en&unit=c "
				   "HTTP/1.1"
				   "\r\n"
				   "Host:api.seniverse.com\r\n"
				   "\r\n"
		    ,KEY,LOCAL);


	//5.說明雙方建立連線,此時可以利用HTTP協議傳送請求資訊,並等待伺服器的響應  基於請求/響應
	send(tcp_socket,reqbuf,strlen(reqbuf),0);

	//6.等待伺服器的響應
	char recvbuf[1024] = {0};
	
	recv(tcp_socket,recvbuf,sizeof(recvbuf),0);  //第一次返回的響應引數
	printf("%s",recvbuf);
	bzero(recvbuf,1024);

	recv(tcp_socket,recvbuf,sizeof(recvbuf),0);  //第二次返回的響應包體
	printf("%s\n",recvbuf);
	
	//7.對響應包體進行JSON解析
	
	//1) 先把獲取的字串轉換為JSON格式
	cJSON * obj = cJSON_Parse(recvbuf);

	//2) 把解析之後的JSON格式進行輸出,用於除錯
	printf("%s\n",cJSON_Print(obj));

	//3) 對JSON格式進行解析
	cJSON * results = NULL;
	results = cJSON_GetObjectItem(obj, "results");
	printf("array size = %d\n",cJSON_GetArraySize(results));

	//4)對溫度進行解析
	cJSON * result = NULL;
	cJSON_ArrayForEach(result, results)
    {
        cJSON * now = cJSON_GetObjectItem(result, "now");
        cJSON * temperature = cJSON_GetObjectItem(now,"temperature");

        printf("temperature : %s\n", temperature->valuestring);

        printf("temperature : %d\n", atoi(temperature->valuestring));
    }
    return 0;
}

相關文章