首页 > 编程语言 >网络编程练习题---利用cJSON库对服务器返回的JSON格式数据完成解析

网络编程练习题---利用cJSON库对服务器返回的JSON格式数据完成解析

时间:2024-06-11 21:21:42浏览次数:11  
标签:练习题 库对 socket cJSON errno tcp flag include

目录

题目


利用某些平台(聚合API、百度AI、科大讯飞API)的API接口,利用HTTP协议向服务器发送请求,并接受服务器的响应,要求利用cJSON库对服务器的响应数据进行解析,并输出到终端。

注意事项

1.预测的日期开始时间为2010-01-01

2."老黄历"API 服务器返回值是将响应包体与响应行一同返回,所以该程序只需要对服务器返回值接收一次,再利用strstr进行找寻响应包体,最后完成JASON格式数据的解析,但是,这种返回方式不是固定的。例如:“天气预报”API返回数据将响应行与响应包体分为两次发出,所以需要接收两次。

3.该程序代码使用了cJSON库,所以需要用户提前下载并将cJSON.c和cJSON.h加入程序文档。

实现代码

/********************************************************************************
*
*	file name:	demo.c
*	author	 :  [email protected] 
*	date	 :  2024/06/11
*	function :  
*               该案例是学习掌握对JSON格式服务器响应数据的解析与构造
*				使用“聚合数据”官网提供的免费接口“老黄历”作为学习例子
* 	note	 :  
*				1.预测的日期开始时间为2010-01-01
*				2."老黄历"API 服务器返回值是将响应包体与响应行一同返回,所以该程序只需要
*					对服务器返回值接收一次,再利用strstr进行找寻响应包体,最后完成JASON
*					格式数据的解析,但是,这种返回方式不是固定的。例如:“天气预报”API返回
*					数据将响应行与响应包体分为两次发出,所以需要接收两次。
*				3.该程序代码使用了cJSON库,所以需要用户提前下载并将cJSON.c和cJSON.h加入
*					程序文档。
*   version  :
*
*	CopyRight (c)  2023-2024   [email protected]   All Right Reseverd 
*
* ******************************************************************************/
/****************************头文件*********************************************/
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/select.h>
#include "cJSON.h"
#include <string.h>

/****************************宏定义*********************************************/
#define HOST "v.juhe.cn"              					  //服务器域名
#define PORT 80                       					  //http协议端口号
#define BUFSIZE 4096                   					  //自定义缓冲区大小
#define KEY  "..."			 							  //API需要的密钥(在个人中心->我的数据,接口名称上方查看)
#define DATE "2024-06-12"								  //想要预测日期,格式2014-09-09


int main(int argc, char **argv)
{
    //创建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);
	}

	//向服务器发送请求之前,需要设置目标端口和目标地址
	struct sockaddr_in  dest_addr;
	socklen_t flag_dest = sizeof(dest_addr);

	dest_addr.sin_family 		= AF_INET; 						//协议族,是固定的
	dest_addr.sin_port   		= htons(PORT);			//服务器运行进程的端口号,必须转换为网络字节序

	//利用gethostbyname函数接口,获取服务器域名所包含的信息---即获取服务器的ip
    struct hostent *hostent =  gethostbyname(HOST);
	if(hostent == NULL)
	{
		fprintf(stderr, "ip get error,errno:%d,%s\n",errno,strerror(errno));
		exit(2);
	}
	//存储服务器IP地址,必须转换为点分十进制字符串形式
	dest_addr.sin_addr.s_addr   = inet_addr("203.107.54.210");		

	//使用connect函数接口向服务器发起连接申请
	int flag_connect = connect(tcp_socket, (struct sockaddr *)&dest_addr, flag_dest);
	if(flag_connect == -1)
	{
		fprintf(stderr, "connect socket error,errno:%d,%s\n",errno,strerror(errno));
		exit(3);
	}

	//连接成功后,向服务器发送请求
	char buf[BUFSIZE] = {0};
	sprintf(buf, "POST http://v.juhe.cn/laohuangli/d?key=%s&date=%s HTTP/1.1\r\n"
				"HOST: %s\r\n"
				"Content-Type: application/x-www-form-urlencoded\r\n"
				"\r\n"
				,KEY
				,DATE
				,HOST);

	int ret = write(tcp_socket,buf,strlen(buf));
    if (ret < 0)
	{
        fprintf(stderr,"send data fail! errno:%d, errmsg:'%s'\n\n",errno, strerror(errno));
        exit(4);

    }
	else
	{
        printf("send data success, length:%d byte!\n\n", ret);
    }

	//利用select监测套接字状态,当服务器发送数据时,进行接收操作
	fd_set t_set1;
	struct timeval tv;

	//清零集合,并设置超时为五秒钟
	FD_ZERO(&t_set1);
	tv.tv_usec = 0;			//微秒为单位
	tv.tv_sec = 5;			//设置等待时间为五秒


	// 执行“少量多次”的规则,监测套接字状态
	while(1)
	{
		//把套接字加入集合中
		FD_SET(tcp_socket, &t_set1);
		int flag_slect = select(tcp_socket + 1, &t_set1, NULL, NULL, &tv);
		printf("flag_slect = %d\n",flag_slect);
		//检测集合读状态失败
		if(flag_slect < 0)
		{
			close(tcp_socket);//关闭套接字
			fprintf(stderr,"read data fail! errno:%d, errmsg:'%s'\n\n",errno, strerror(errno));
            exit(5);
		}
		//超时则重新监测
		if(flag_slect == 0)
		{
			printf("h:%d sec:%ld usec:%ld\n\n", flag_slect, tv.tv_sec, tv.tv_usec);
			continue;
		}
		//服务器已经发送数据,可以执行读取操作
		if(flag_slect > 0)
		{
			memset(buf, 0, BUFSIZE);
            int i = read(tcp_socket, buf, BUFSIZE);
			printf("%s\n", buf);
			if (i == 0)
			{
                close(tcp_socket);//关闭套接字
                fprintf(stderr,"read data fail! errno:%d, errmsg:'%s'\n\n",errno, strerror(errno));
                exit(6);
            }
			break;
		}
	}

	//对读取到的数据进行处理,由于响应包体跟响应行+响应字段粘合在一起,所以需要先对获取数据作初步处理
	char *buf1 = strstr(buf, "{");
	// 1. 将存储JSON格式的字符串转换成JASON格式数据
	cJSON *json = cJSON_Parse(buf1);
	//2. 对转换后的数据进行输出调试
	char *string = cJSON_Print(json);
	printf("%s\n", string);
	//3. 练习:利用cJSON_GetObjectItem获取指定键名的值
	cJSON *result = cJSON_GetObjectItem(json, "result");
	cJSON *jishen = cJSON_GetObjectItem(result, "jishen");
	char *str_jishen = cJSON_Print(jishen);
	printf("吉神宜趋: %s\n", str_jishen);

	//关闭套接字
	close(tcp_socket);

	return 0;
}

结果展示

image

相关接口指引

标签:练习题,库对,socket,cJSON,errno,tcp,flag,include
From: https://www.cnblogs.com/fly-home/p/18242751

相关文章

  • 网络编程练习题
    网络编程代码#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#include<stdio.h>#include<errno.h>#include<sys/socket.h>#include<netinet/in.h>#include<netinet/ip.h>#include<arpa......
  • cJSON学习及简单应用小结
    JSON简介JSON(JavaScriptObjectNotation,JavaScript对象表示法)是一种轻量级的数据交换格式。它基于ECMAScript(欧洲计算机制造商协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。以下是JSON......
  • 【机器学习基础】Python编程07:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • 【机器学习基础】Python编程08:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • 视频汇聚EasyCVR安防监控系统GA/T 1400协议视图库对接:技术实现与应用
    随着信息技术的不断发展,各类协议标准在各个领域得到了广泛应用。GA/T1400协议作为公安视频监控系统中的一种重要标准,对于提升公安工作的信息化水平、加强社会治安防控具有重要意义。本文将重点探讨GA/T1400协议视图库对接的技术实现及应用价值。一、GA/T1400协议概述GA/T1400协......
  • (十六)统计学基础练习题十(选择题T451-478)
    本文整理了统计学基础知识相关的练习题,共50道,适用于想巩固统计学基础或备考的同学。来源:如荷学数据科学题库(技术专项-统计学三)。序号之前的题请看往期文章。451)452)453)454)455)456)457)458)459)460)461)462)463)464)465)466)467)468)469)470)471)472)......
  • 网络编程练习题---利用TCP协议完成客户端与服务端点对点通信
    目录题目一解析代码实现题目二:解析代码实现tcp_client.ctcp_server.c题目一设计程序实现解析www.baidu.com的域名,把获取到的百度的IP地址全部输出到终端并验证是否正确。解析主机打算响应某个网站的网络请求,但是只知道网站域名是无法通信的,需要对域名进行地址解析,得到网站的公......
  • 【机器学习基础】Python编程02:五个实用练习题的解析与总结
    Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面:简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些库提供了......
  • (十五)统计学基础练习题九(选择题T401-450)
    本文整理了统计学基础知识相关的练习题,共50道,适用于想巩固统计学基础或备考的同学。来源:如荷学数据科学题库(技术专项-统计学三)。序号之前的题请看往期文章。401)402)403)404)405)406)407)408)409)410)411)412)413)414)415)416)417)418)419)420)421)422)......
  • 网络编程练习题---利用UDP协议实现组播通信
    目录题目解析代码实现题目解析由于该题需要实现组播通信,所以我们需要将套接字文件句柄设置为组播属性,并将需要通信的用户端IP地址,加入组中。由于组播通信需要实现一对多发送消息,所以还需要将套接字文件句柄的广播属性一并开启。由于该题实现过程使用到了线程相关函数接口,所......