• 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
    • 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
    1. 程序出现异常,在处理其中某个文件内容时,我的测试程序出现了异常:
      在这里插入图片描述
      错误提示为,json类型的assert异常:
      在这里插入图片描述
      故而,如果不判断json类型,那么直接调用[],会报异常;
      我再上面的测试代码中,增加了一个关于json类型的判断,代码截图如下:
      在这里插入图片描述
    2. 通过观察rsp.txt文件发现内容上始终不全,例如一个json数据接收不全,在分析libcurl接收代码之后也找到了问题;

    解决方案:

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

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

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

  • 相关阅读:
    Polygon 巨大 的 NFT 市场发生了什么变化?
    随笔荟萃 | sincerity
    linux文件权限常用知识点,基于Linux(openEuler、CentOS8)
    Xilinx cache刷新使用的问题
    【剑指Offer】50. 第一个只出现一次的字符
    MySQL:读写分离-amoeba(7)
    MFC网络编程2——异步套接字
    CSS的布局模式(更新中)
    基于OXC的光电联动全光网组网方案研究与实践
    基本IO接口技术——微机第七章笔记
  • 原文地址:https://blog.csdn.net/shayueqing/article/details/127362907