2022-10-17 我帮你踩了libcurl接收json数据的一些坑

项目场景:

使用libcurl库,发送http接口定时向第三方服务器,获取部分json,数据用于解析,并且得到需要的信息,传给我们的子系统


问题描述

  1. 服务突然发生异常,错误代码与堆栈内存有关,错误码为:0x00000374
    在这里插入图片描述

排查过程:

  1. 通过打日志的方法,记录libcurl接收到的数据保持到本地磁盘,进行分析;
    在这里插入图片描述
    在这里插入图片描述

  2. 编写测试程序,验证每个文件能否被解析;如果可以解析,就把该文件删掉,否则留着;

string src_path; //= string(argv[1]);
	string dst_path; //= string(argv[2]);
	string time; //= string(argv[3]);
	vector<string> m_vecFiles;
	src_path = "D:\\rsp2";

	if (FindFilesInFolder(src_path, m_vecFiles) == true) {

		for (auto& it : m_vecFiles) {

			string rspfilename = src_path+"\\" + it;
			ifstream MyFile1(rspfilename, std::fstream::in);
			bool bl = MyFile1.is_open();
			bool bDelete = false;
			string str;
			while (std::getline(MyFile1, str)) {//和上面的读取方式写法类似,只是每次是读取一整行
				if (str == "start") {
					continue;
				}
				if (str == "end") {
					continue;
				}
				Json::Value root;
				Json::Reader reader;
				if (!reader.parse(str.c_str(), root))
				{
					cout << "解析错误" << rspfilename<< endl;
					continue;
				}
				/*
					注意:json库使用,parse之后,root的类型有可能是json::intvalue
				*/
				if (root.type() != Json::objectValue)
				{
					//非json对象
					bDelete = true;
					cout << "非json对象" << rspfilename << endl;
					continue;
				}
				//不关心Issuccess 和result
				if (root["Data"].isNull()) {
					//为空,则不处理
					//cout << "Data is NUll" << str << endl;
					bDelete = true;
					continue;
				}
				if (!root["Data"].isArray())
				{
					cout << "Data is not Array" << str << endl;
					continue;
				}
				//转换为数组
				Json::Value& data = root["Data"];
				//如果是Null,则全删除
				if (data.size() == 0)
				{
					cout << "Data is null" << str << endl;
					continue;
				}

				//如果有数据,则要和本地数据比较
				//如果多了,则新增,如果一样,则保持,如果少了,则删除
				map<std::string, std::string> newAlarm;
				for (size_t i = 0; i < data.size(); i++) {
					if ((data[i]["DevNum"].isNull()) || (data[i]["CallTime"].isNull()) || (data[i]["CallInfo"].isNull())
						|| (!data[i]["DevNum"].isString()) || (!data[i]["CallTime"].isString()) || (!data[i]["CallInfo"].isString()))
					{
						//不满足解析要求,
						cout << "Data is error" << str << endl;
						continue;

					}
					else {
						cout << "Data is OK" << str << endl;
						bDelete = true;
					}
				}
			}
			MyFile1.close();
			if (bDelete) {
				::DeleteFile(rspfilename.c_str());
			}
		}
  1. 程序出现异常,在处理其中某个文件内容时,我的测试程序出现了异常:
    在这里插入图片描述
    错误提示为,json类型的assert异常:
    在这里插入图片描述
    故而,如果不判断json类型,那么直接调用[],会报异常;
    我再上面的测试代码中,增加了一个关于json类型的判断,代码截图如下:
    在这里插入图片描述
  2. 通过观察rsp.txt文件发现内容上始终不全,例如一个json数据接收不全,在分析libcurl接收代码之后也找到了问题;

解决方案:

  1. 修改Libcurl接收代码,libcurl的接收函数回调函数,是有可能多次调用的;
    在这里插入图片描述
  1. 针对文本数据,除了判断能否解析之外,还需要判断是否是Json::objectValue;

在这里插入图片描述在这里插入图片描述

最后,记录此bug, 希望对大家开发相关程序有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShaYQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值