MFC学习之vc通过HTTP请求:Get或Post方式获取JSON信息(亲测可用)

2023-05-16

前段时间公司项目需要跟上一级平台对接一些采集回来的数据,通过HTTP,post方法上传JSON信息到指定的接口地址。
本来呢?我在入职时是面试的售后岗,一家小公司,当时公司软件方面一直是外包给其他人代写的,因为涉及到的程序结构不是很复杂,也没有太多新的定制,有初版之后改动不大的情况下,人家都帮忙弄了。
面试的时候,几个领导也简单了解过,知道我懂一些开发的东西,去年也多多少少,帮他们写过一些调试类的小工具。就落下了这个把柄,本来公司没个正经的开发人员,活也不是很多,就又被强制上岗了。

先说下遇到的问题,在网上找了两个相关的类,自己测试之后怎么都不能通信,说实话怎么也不知知道哪里的原因。
一个HTTPTools类和一个WinnetHttp类,需要的大家可以搜“MFC vc通过HTTP请求:Get或Post方式获取JSON信息”,资源已上传,自行下载。
我感觉是可能一个地址解析的时候有问题,但是单步跟过,没有发现什么一样;另一个可能是请求协议头的问题,但是也试了好几个也不行。

这个是WinnetHttp类里的发送和接收部分,大家可以看下或者搜索下载测试。

void CWininetHttp::ConnectAndRecv(const std::string &lpUrl, HttpRequest type, std::string &strHeader, std::string &strPostData)
{
	m_bSucess = true;
	try
	{
		INTERNET_PORT port    = INTERNET_DEFAULT_HTTP_PORT;  
		std::string strHostName = "";  
		std::string strPageName = "";  

		ParseURLWeb(lpUrl, strHostName, strPageName, port);  
		printf("lpUrl:%s,\nstrHostName:%s,\nstrPageName:%s,\nport:%d\n",lpUrl.c_str(),strHostName.c_str(),strPageName.c_str(),(int)port); 
		m_hConnect = InternetConnectA(m_hSession, strHostName.c_str(), port, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);  
		if ( NULL == m_hConnect )  
		{  
			throw Hir_ConnectErr;  
		}  
		std::string strRequestType;  
		if ( Hr_Get == type )  
		{  
			strRequestType = "GET";  
		}  
		else  
		{  
			strRequestType = "POST";  
		}  

		m_hRequest = HttpOpenRequestA(m_hConnect,strRequestType.c_str(), strPageName.c_str(),"HTTP/1.1", NULL, NULL, INTERNET_FLAG_RELOAD, NULL);  
		if ( NULL == m_hRequest )  
		{  
			throw Hir_InitErr;  
		}  

		DWORD dwHeaderSize = (strHeader.empty()) ? 0 : strlen(strHeader.c_str());  
		BOOL bRet = FALSE; 
		DWORD d2=0;
		if ( Hr_Get == type )  
		{  
			bRet = HttpSendRequestA(m_hRequest,strHeader.c_str(),dwHeaderSize,NULL, 0);  
		}  
		else  
		{  
			DWORD dwSize = (strPostData.empty()) ? 0 : strlen(strPostData.c_str());  
			DWORD d1 = GetTickCount();
			bRet = HttpSendRequestA(m_hRequest,strHeader.c_str(),dwHeaderSize,(LPVOID)strPostData.c_str(), dwSize); 
			d2 = GetTickCount()-d1;
		}  
		if ( !bRet )  
		{  
			DWORD n = GetLastError();
			throw Hir_SendErr;  
		}  

		char szBuffer[READ_BUFFER_SIZE + 1] = {0};  
		DWORD dwReadSize = READ_BUFFER_SIZE;  
		if ( !HttpQueryInfoA(m_hRequest, HTTP_QUERY_RAW_HEADERS, szBuffer, &dwReadSize, NULL) )  
		{  
			throw Hir_QueryErr;  
		}  
		if ( NULL != strstr(szBuffer, "404") )  
		{  
			throw Hir_404;  
		}  

		while( true )  
		{  
			bRet = InternetReadFile(m_hRequest, szBuffer, READ_BUFFER_SIZE, &dwReadSize);  
			if ( !bRet || (0 == dwReadSize) )  
			{  
				break;  
			}  
			szBuffer[dwReadSize]='\0';  
			m_strRet.append(szBuffer);  
		}
	}
	catch(HttpInterfaceError error)  
	{
		m_strErr = m_mapErr[error];
		m_bSucess = false;
	}
	m_bExit = true;
	std::unique_lock <std::mutex> lck(mtx);
	cv.notify_one();
}

这个是HTTPTools类里的发送和接收部分,大家可以看下或者搜索下载测试。

int HttpTools::HttpRequest(const std::wstring& strMethod,
	const std::wstring& strUrl,
	const std::wstring& postData,
	std::wstring& response,
	const std::wstring& strAgent)
{
	CString strServer;
	CString strObject;
	DWORD dwServiceType;
	INTERNET_PORT nPort;
	response.clear();

	//先解析一下url
	BOOL bParseUrl = AfxParseURL(strUrl.c_str(), dwServiceType, strServer, strObject, nPort);

	if (AFX_INET_SERVICE_HTTP != dwServiceType && AFX_INET_SERVICE_HTTPS != dwServiceType)
	{
		return HTTP_FAILURE;
	}

	CInternetSession *pSession = new CInternetSession(strAgent.c_str());
	CHttpConnection  *pConnection = NULL;
	CHttpFile        *pHttpFile = NULL;

	try
	{
		//创建一个http链接
		pConnection = pSession->GetHttpConnection(strServer,
			dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_CONNECT : SECURE_CONNECT,
			nPort);
		//开始一个http请求,映射成HttpFile
		pHttpFile = pConnection->OpenRequest(strMethod.c_str(), strObject,
			NULL, 1, NULL, NULL,(dwServiceType == AFX_INET_SERVICE_HTTP ? NORMAL_REQUEST : SECURE_REQUEST));

		//DWORD dwFlags;
		//m_pFile->QueryOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);
		//dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
		//set web server option
		//m_pFile->SetOption(INTERNET_OPTION_SECURITY_FLAGS, dwFlags);

		pHttpFile->AddRequestHeaders(L"Accept: *,*/*");
		//pHttpFile->AddRequestHeaders(L"Accept-Language: zh-cn");
		//pHttpFile->AddRequestHeaders(L"Content-Type: application/x-www-form-urlencoded;charset=utf-8;");
		//pHttpFile->AddRequestHeaders(L"Accept-Encoding: gzip, deflate");

		pHttpFile->AddRequestHeaders(L"Accept:application/json;");
		pHttpFile->AddRequestHeaders(L"Content-Type:application/json;charset=utf-8;");
		pHttpFile->AddRequestHeaders(L"Content-Type:multipart/form-data;");


		//发送请求 转UTF8
		std::string pData = wstringToUtf8(postData);
		BOOL bResult = pHttpFile->SendRequest(NULL, 0, (LPVOID)pData.data(), (DWORD)postData.length());// *sizeof(char));
		//pHttpFile->SendRequest(NULL, 0, (LPVOID)postData.data(), postData.length() * sizeof(wchar_t));
		if (!bResult)
		{
			return HTTP_FAILURE;
		}

		char szChars[1024] = { 0 };
		std::string strRawResponse;
		UINT nReaded = 0;
		while ((nReaded = pHttpFile->Read((void*)szChars, 1024)) > 0)
		{
			strRawResponse.append(szChars, nReaded);
		}

		/* 把回复结果转为unicode编码,大多数情况下是需要这么做的*/
		int unicodeLen = MultiByteToWideChar(CP_UTF8, 0, strRawResponse.c_str(), -1, NULL, 0);
		WCHAR *pUnicode = new WCHAR[unicodeLen];
		memset(pUnicode, 0, (unicodeLen)*sizeof(wchar_t));

		MultiByteToWideChar(CP_UTF8, 0, strRawResponse.c_str(), -1, pUnicode, unicodeLen);
		std::wstring unicodeRsp;
		unicodeRsp.assign(pUnicode, unicodeLen);
		// 返回值
		response = unicodeRsp;

		delete[]pUnicode;
		pUnicode = NULL;


		if (NULL != pHttpFile)
		{
			pHttpFile->Close();
			delete pHttpFile;
			pHttpFile = NULL;
		}
		if (NULL != pConnection)
		{
			pConnection->Close();
			delete pConnection;
			pConnection = NULL;
		}
		if (NULL != pSession)
		{
			pSession->Close();
			delete pSession;
			pSession = NULL;
		}
	}
	catch (CInternetException* e)
	{
		if (NULL != pHttpFile)
		{
			pHttpFile->Close();
			delete pHttpFile;
			pHttpFile = NULL;
		}
		if (NULL != pConnection)
		{
			pConnection->Close();
			delete pConnection;
			pConnection = NULL;
		}
		if (NULL != pSession)
		{
			pSession->Close();
			delete pSession;
			pSession = NULL;
		}


		DWORD dwErrorCode = e->m_dwError;
		e->Delete();

		DWORD dwError = GetLastError();

		if (ERROR_INTERNET_TIMEOUT == dwErrorCode)
		{
			return HTTP_OUTTIME;
		}
		else
		{
			return HTTP_FAILURE;
		}
	}
	return HTTP_SUCCESS;
}

以上两种方法自己亲测不能用,具体原因不知道,也找了好多其他实例测试过,最后用的也给大家贴在这了,记得收藏哦!!!

bool PostContent(CString strUrl, const CString&strPara, CString &strContent)

{

	try {

		bool bRet = false;

		CString strServer, strObject, strHeader, strRet;

		unsigned short nPort;

		DWORD dwServiceType;

		if (!AfxParseURL(strUrl, dwServiceType, strServer, strObject, nPort))
		{
			return false;
		}

		CInternetSession sess;//Create session

		CHttpFile*pFile;

		CHttpConnection*pServer = sess.GetHttpConnection(strServer, nPort);

		if (pServer == NULL)
		{
			return false;
		}

		pFile = pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST, strObject, NULL, 1, NULL, NULL, INTERNET_FLAG_EXISTING_CONNECT);

		if (pFile == NULL)
		{
			return false;
		}

		CString strHeaders = "Content-Type:application/x-www-form-urlencoded;";
		//CString strHeaders = "Accept:application/json;";
		int istrlen = strPara.GetLength();

		pFile->SendRequest(strHeaders, (LPTSTR)(LPCTSTR)strPara, strPara.GetLength());

		//AfxMessageBox((LPTSTR)(LPCTSTR)strPara);

		CString strSentence;
		DWORD dwStatus;
		DWORD dwBuffLen = sizeof(dwStatus);
		BOOL bSuccess = pFile->QueryInfo(HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,&dwStatus, &dwBuffLen);

		if (bSuccess && dwStatus >= 200 && dwStatus<300)
		{
			char buffer[256];
			memset(buffer, 0, 256);
			int nReadCount = 0;
			while ((nReadCount = pFile->Read(buffer, 2048)) > 0)
			{
				strContent += buffer;
				memset(buffer, 0, 256);
			}
			bRet = true;
		}

		else
		{
			bRet = false;
		}

		pFile->Close();
		sess.Close();
		return bRet;
	}

	catch (...)
	{
		int nCode = GetLastError();
		return false;
	}
}

具体哪里的问题,有知道的朋友可以一起讨论,可能我比较笨,第一次弄这个东西,东拼西凑反正能用了,哈哈哈… …

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MFC学习之vc通过HTTP请求:Get或Post方式获取JSON信息(亲测可用) 的相关文章

  • 在线安装eclipse中html/jsp/xml editor插件(非常可靠),eclipseeditor

    在线安装eclipse中html jsp xml editor插件 xff08 非常可靠 xff09 xff0c eclipseeditor 之前有一篇文章也是安装eclipse中的web开发插件 xff0c 但是经过很多人使用 xff0c
  • android 基于ijkplayer项目进行的播放器

    jjdxm ijkplayer 项目地址 xff1a jjdxm ijkplayer 简介 xff1a 基于 ijkplayer 简单的 UI 界面 当前项目是基于 ijkplayer 项目进行的播放器界面 UI 封装 是一个适用于 And
  • android 类似豆瓣读书,提供一个书籍查看、搜索、交流的平台

    SoleBooks 项目地址 xff1a Blankeer SoleBooks 简介 xff1a 类似豆瓣读书 xff0c 提供一个书籍查看 搜索 交流的平台 LeanCloud MVP RxJava 截图 项目描述 数据来源 数据来源于豆
  • C++中::与.的区别

    xff08 1 xff09 是域作用符 xff0c 是各种域性质的实体 xff08 比如类 xff08 不是对象 xff09 名字空间等 xff09 调用其成员专用的 xff08 如果有个局部变量与全局变量同名 xff08 假设都是int
  • Java防止SQL注入

    1 定义 xff1a 所谓SQL注入 xff0c 就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串 xff0c 最终达到欺骗服务器执行恶意的SQL命令 2 防止SQL注入的方法 xff1a A xff1a 使用Pre
  • 高仿萌聚 app ,内容简直是宅男福利啊

    mengqu 项目地址 xff1a panacena mengqu 简介 xff1a 高仿萌聚 app xff0c 内容简直是宅男福利啊 xff01 高仿萌趣 app 最近下了个叫做 萌趣 的 app xff0c 内容简直是宅男福利啊 xf
  • 人脸识别扫描(活体检测功能,眨眼、摇头、点头),身份证认证

    FaceAC 项目地址 xff1a sxpl FaceAC 简介 xff1a 人脸识别扫描 xff08 活体检测功能 xff0c 眨眼 摇头 点头 xff09 xff0c 身份证认证 更多 xff1a 作者 提 Bug 标签 xff1a 人
  • 全开源即时通讯(IM)系统 高仿微信

    android chat 项目地址 xff1a wildfirechat android chat 简介 xff1a 全开源即时通讯 IM 系统 高仿微信 更多 xff1a 作者 提 Bug 官网 标签 xff1a 野火 IM 是一套跨平台
  • OpenCV与机器视觉

    最近在网易云课堂把南科大于仕琪团队的OpenCV教程完整看了一遍 xff0c 对图像处理或者机器视觉又有了一个系统性的理解 OpenCV中文网站就是他创建的 xff0c 他的研究团队及其相应成果可以在个人网站中查阅 回想过去在图像处理方面的
  • Virtual Box+Ubuntu20.04+ROS2 Foxy配置

    ROS从最早的正式版本Box Turtle到现在也十几年了 而ROS2出来也挺久了 xff0c 一直没机会看看 好久也没弄ROS xff0c 这几天捣鼓了捣鼓 目录 1 Virtual Box安装Ubuntu20 04 2 ROS2 Fox
  • TI CC265x的IIC通讯读取IMU BMI08x数据

    SmartLink CC265x是TI公司出的无线MCU平台器件 最近玩了个小项目用TI的CC265x平板IIC接口通讯 xff0c 获取博世BMI08x陀螺仪 加速度计传感器的数据 本篇博客亦是对博客 树莓派IIC通讯获取BMI08x I
  • 三种方法在ROS中加载Qt库进行GUI设计

    编写ros程序 xff0c 因为有时会涉及到界面设计 xff0c 所以本人主要用的QtCreator IDE 首先当然是安装QtCreator xff0c 这个网上有很多安装教程和下载资源 xff0c 非常简单 由于Qt的工程大多采用qma
  • 在ROS中处理yaml文件

    ROS中的参数服务器 xff08 Parameter Server xff09 的相关操作可参见roscpp tutorials Tutorials Parameters 如果想要载入参数 xff0c 可以通过编写yaml文件 xff0c
  • ROS动态调参(dynamic reconfigure)客户端服务端之C++ Python实现

    在ROS系统中 xff0c 我们需要实时修改参数 xff0c 并能马上看到运行效果 这一功能是通过ros dynamic reconfigure包实现的 官网教程如下 xff1a dynamic reconfigure Tutorials
  • ROS中slam_gmapping、map_server源码解读及其librviz的使用

    SLAM全称simultaneous localization and mapping xff0c 即实时定位与地图构建 也就是说导航离不开地图 xff0c 目前常用的地图构建方法有三种 xff1a 1 gmapping xff0c 一种基
  • 记 - PC视频播放最强画质教程(Potplayer + madVR)

    PC视频播放最强画质教程 前言 xff1a 本次使用到的软件 工具 Potplayer播放器 Potplayer是目前我用到的最好用的宝藏视频播放软件 xff1a 内存占用低 无广告 支持视频格式多 功能强大 扩展性高 界面唯美 xff08
  • 【三维深度学习】多视角立体视觉 MVSNet代码解读

    MVSNet通过将相机几何参数编码到网络中 xff0c 实现了端到端的多视角三维重建 xff0c 并在性能和视觉效果上超越了先前算法 xff0c 并在eccv2018 oral中发表 模型主要包含四个主要步骤 xff1a 图像特征抽取 多视
  • 【pandas】删除满足条件元素所在的行

    在数据清洗时 xff0c 需要按照一定条件删除某些数据样本 xff0c 利用布尔表达式 索引和drop方法可以实现 1 pandas drop df 61 df drop df lt some boolean condition gt in
  • 【AI视野·今日Robot 机器人论文速览 第八期】Wed, 16 Jun 2021

    AI视野 今日CS Robotics 机器人学论文速览 Wed 16 Jun 2021 Totally 13 papers x1f449 上期速览 更多精彩请移步主页 Daily Robotics Papers Constrained Mo
  • 【CVPR2022】论文列表与下载——PartTwo

    CVPR2022将于6月22日召开 x1f389 x1f389 x1f389 xff0c 本次会议共收录了2067篇论文 由于数量较多 xff0c 本文将分四个子文章呈现 xff0c 可直接点击论文标题获取文档 x1f4c3 第一部分 x1

随机推荐

  • 【CVPR2022】论文列表与下载——PartThree

    CVPR2022将于6月22日召开 x1f389 x1f389 x1f389 xff0c 本次会议共收录了2067篇论文 由于数量较多 xff0c 本文将分四个子文章呈现 xff0c 可直接点击论文标题获取文档 x1f4c3 第一部分 x1
  • 【CVPR2022】论文列表与下载——PartFour

    CVPR2022将于6月22日召开 x1f389 x1f389 x1f389 xff0c 本次会议共收录了2067篇论文 由于数量较多 xff0c 本文将分四个子文章呈现 xff0c 可直接点击论文标题获取文档 x1f4c3 第一部分 x1
  • Python三维绘图--Matplotlib

    Python三维绘图 在遇到三维数据时 xff0c 三维图像能给我们对数据带来更加深入地理解 python的matplotlib库就包含了丰富的三维绘图工具 1 创建三维坐标轴对象Axes3D 创建Axes3D主要有两种方式 xff0c 一
  • 【深度学习】三维点云数据集总结

    点云数据集总结 三维点云数据 xff0c 三维深度学习 1 ShapeNet ShapeNet是一个丰富标注的大规模点云数据集 xff0c 其中包含了55中常见的物品类别和513000个三维模型 2 ShapeNetSem 这是一个小的数据
  • git push代码到远程新分支

    Git push 获取远程代码修改后 想要push到远端与原来不同的新分支 xff0c 可以使用下面的命令实现 xff1a git push origin 本地分支 远端希望创建的分支 例如git下来的分支为master span clas
  • 【numpy求和】numpy.sum()求和

    numpy sum a axis 61 None dtype 61 None out 61 None keepdims 61 initial 61 source 用于计算array元素的和 python中常用的numpy进行数学计算 xff
  • Nuttx romfs与启动脚本rcS

    ARM系统上电后 xff0c 系统将flash地址映射到零地址处 xff0c 处理器从零地址处开始运行第一条指令 而在零地址处 xff0c 一般是系统复位中断向量 xff0c 此处存放的是一条跳转指指令 xff0c 通过该条换指令 xff0
  • 在终端/命令行下打开文件浏览器窗口--Win cmd &Ubuntu terminal

    在命令行下想要可视化查看文件 xff0c 可以使用命令直接打开图形化窗口 1 Windows windows上可以使用explorer exe打开资源管理器 xff1a explorer exe span class token keywo
  • 127.0.0.0与0.0.0.0的区别

    1 IP地址分类 ref https tools ietf org html rfc1700 page 3 IP地址表示 IP地址由两个部分组成 xff0c net id和host id xff0c 即网络号和主机号 net id 表示ip
  • 【python】代码换行的几种方法

    代码太长怎么办 xff0c 反斜杠 引号 34 34 34 39 来帮忙 xff01 在写list或者较长的字符串时候 xff0c 或者多个循环造成IDE不够用时 xff0c 就需要代码换行了 主要的代码换行有通用的反斜杠 和针对字符串起作
  • 自己动手写C++迭代器

    综述 关于STL iterator和 iterator adapter 的部分我已在先前的博客 stl源码剖析笔记之iterator 中有所提及 xff0c 下面我们可以试着自己动手写一个简单的迭代器工具 step iterator xff
  • 【STM32F0】Keil 查看局部变量显示<not in scope>

    现象 xff1a 在进行STM32F0开发的时候出现了 调试代码 xff0c 添加变量Watch时 xff0c 显示not in scope 处理方式 xff1a 因为代码开了优化的处理 xff0c 把优化改到Level0 就可以解决问题
  • error: undefined reference to '__dso_handle'解决方案

    error undefined reference to 39 dso handle 39 解决方案 home NDK android ndk r9 sources cxx stl gnu libstdc 43 43 4 7 libs ar
  • ARM里的大端格式和小端格式分别是什么意思?

    当前的存储器 xff0c 多以byte为访问的最小单元 xff0c 当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题 于是端 endian 的问题应运而生了 对于不同的存储方法 就有大端 big endian 和小端
  • STM32串口通信(基于缓冲区)编程及遇到的问题总结

    在写串口通信前阅读了STM32中文参考手册 xff0c 然后满心澎湃地写代码 在这个过程中遇一些让人郁闷的事情 xff0c 目前这些问题目前已经解决了 xff08 嘿嘿嘿 xff09 xff0c 特此来总结一番 串口的使用步骤大概如下 xf
  • 主板串口FIFO大小设置

    FIFO大小和芯片 驱动有关系 xff0c 可以在设备管理器里面调整大小 1 进入设备管理器 xff0c 右键选择串口属性 2 在端口设置里面选择高级 3 可以单独设定每一个串口的接收和发送区大小
  • mac终端 python scrapy爬虫 zsh: no matches found

    在学习Python爬虫时 xff0c 进行到scrapy板块 xff0c 执行genspider命令 输入scrapy genspider tongcheng https bj 58 com sou key 61 E5 89 8D E7 A
  • JSESSIONID的简单说明

    1 第一次访问服务器的时候 xff0c 会在响应头里面看到Set Cookie信息 只有在首次访问服务器的时候才会在响应头中出现该信息 上面的图JSESSIONID 61 ghco9xdnaco31gmafukxchph Path 61 a
  • 史上最全的常用开发工具类收集(持续更新中)

    外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img BtY85pbk 1577412535564 https img shields io badge QQ群 523167548 20 ff69b4 svg API
  • MFC学习之vc通过HTTP请求:Get或Post方式获取JSON信息(亲测可用)

    前段时间公司项目需要跟上一级平台对接一些采集回来的数据 xff0c 通过HTTP xff0c post方法上传JSON信息到指定的接口地址 本来呢 xff1f 我在入职时是面试的售后岗 xff0c 一家小公司 xff0c 当时公司软件方面一