C++使用winhttp以POST/GET方法实现报文转发与接收

这里仅仅是我的开发的一点经验,
C++通过httppost实现接口信息交互。

准备

c++调用httppost方法实现报文转发接收之前的准备工作,先通过postman测试接口是否连通。
postman调用

这里的是地址+端口+接口 后面一定要加上 ?param=
然后看返回的报文是否正确

其他情况

如果电脑没有postman可以用ie浏览器代替,地址+端口+接口 后面一定要加上 ?param= +发送报文,回车查看页面。

代码实现

包含文件

下面 包含的头文件与lib文件

#include <winhttp.h>
#pragma comment(lib,"winhttp.lib")

实现代码

下面 实现代码部分

//http post方法发送文本
//host ip或者网址
//port 端口号
//path 资源地址. 如:www.baidu.com/HELLO/中的 HELLO/
//send 发送的内容(body部分)
//resp 接收的内容(body部分)
int HttpPost(CString host, int port, CString path, CString send, CString & resp)
{
	DWORD dwSize = 0;
	DWORD dwDownloaded = 0;
	HINTERNET  hSession = NULL;
	HINTERNET hConnect = NULL;
	HINTERNET hRequest = NULL;
	BOOL  bResults = FALSE;
	int ret = 0;
	hSession = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
	if (NULL == hSession) {
		return -1;
	}

	hConnect = WinHttpConnect(hSession, host, port, 0);
	if (NULL == hConnect) {
		WinHttpCloseHandle(hSession);
		return -1;
	}
	CString a = path + send;
	//hRequest = WinHttpOpenRequest(hConnect, _T("POST"), a, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE);//https
		hRequest = WinHttpOpenRequest(hConnect, _T("POST"), a, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);//http
	if (NULL == hRequest) {
		WinHttpCloseHandle(hSession);
		WinHttpCloseHandle(hConnect);
		return -1;
	}

	LPCWSTR header = _T("Content-type: text/plain; charset=utf-8/r/n");
	SIZE_T len = lstrlenW(header);

	bResults = WinHttpAddRequestHeaders(hRequest, header, DWORD(len), WINHTTP_ADDREQ_FLAG_ADD);
	if (!bResults) {
		ret = -1;
		WinHttpCloseHandle(hSession);
		WinHttpCloseHandle(hConnect);
		WinHttpCloseHandle(hRequest);
		return -1;
	}
	USES_CONVERSION;
	char * sbuf = T2A(send);
	int slen = strlen(sbuf);
	bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, slen, 0);
	if (!bResults) {
		ret = -1;
		WinHttpCloseHandle(hSession);
		WinHttpCloseHandle(hConnect);
		WinHttpCloseHandle(hRequest);
		return -1;
	}

	bResults = WinHttpReceiveResponse(hRequest, NULL);
	if (!bResults) {
		ret = -1;
		WinHttpCloseHandle(hSession);
		WinHttpCloseHandle(hConnect);
		WinHttpCloseHandle(hRequest);
		return -1;
	}
	const int mxlen = 10240;
	char const * pszOutBuffer = new char[10240];
	if (NULL == pszOutBuffer) {
		WinHttpCloseHandle(hSession);
		WinHttpCloseHandle(hConnect);
		WinHttpCloseHandle(hRequest);
		return -1;
	}
	char* p = (char*)pszOutBuffer;
	ZeroMemory(p, mxlen);
	int cnt = 0;
	do
	{
		dwSize = 0;
		if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
		{
			//printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
			break;
		}
		if (!dwSize)
			break;

		if (WinHttpReadData(hRequest, (LPVOID)(p + cnt), dwSize, &dwDownloaded))
		{
			cnt += dwSize;
			//printf("Error %u in WinHttpReadData.\n", GetLastError());
		}
		else {
			//printf("Error %u in WinHttpReadData.\n", GetLastError());
		}
		if (!dwDownloaded)
			break;
	} while (dwSize > 0);

	resp = CString(pszOutBuffer);

	resp = U8ToUnicode(T2A(resp));
	delete[] pszOutBuffer;
	WinHttpCloseHandle(hSession);
	WinHttpCloseHandle(hConnect);
	WinHttpCloseHandle(hRequest);
	return 0;
}

函数解释

WinHttpOpen 打开函数返回值为句柄
WinHttpConnect(hSession(句柄), host(地址), port(端口号), 0) 连接函数
WinHttpOpenRequest(hConnect, _T(“POST”)(NULL则是GET), a(调用接口+数据), _T(“HTTP/1.1”), WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0(0为http,WINHTTP_FLAG_SECURE为https)) 创建一个http请求处理
WinHttpAddRequestHeaders(hRequest, header(请求的头域字符串), DWORD(len)(头域长度), WINHTTP_ADDREQ_FLAG_ADD) 添加一个HTTP的请求头域
WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS(请求头域), 0(头域长度), NULL, 0(没有数据发送时,设置为0), slen(总发送的数据的长度), 0()) 发送请求数据
WinHttpReceiveResponse(hRequest, NULL)
通过调用WinHttpOpenRequest且调用WinHttpSendRequest返回的句柄 等待WinHttpSendRequest发送完成时调用WinHttpReceiveResponse
WinHttpQueryDataAvailable(hRequest, &dwSize) 请求返回的数据量,以字节为位进行读取
WinHttpReadData(hRequest, (LPVOID)(p + cnt)(接收数据的缓冲区), dwSize(缓冲区大小长度), &dwDownloaded(传出接收的字节数)) 读取返回的数据
WinHttpCloseHandle(句柄) 关闭一个HINTERNET句柄
更详细的函数说明查看:https://blog.csdn.net/fengsh998/article/details/8201591

调用注意事项

在使用**WinHttpReadData()**函数的时候,有可能一次接收的数据不完整,则需要设置循环接收直到缓冲区大小长度为0;
一般httppost发送的报文为UTF-8,而我们需要发送的报文为GBK格式,所以发送的报文和接收的报文需要做处理,不然返回数据为乱码,或者发送报文数据不正确。

如果您想直接使用WinHttp库发送HTTP POST请求,可以使用以下代码: ```cpp #include <QtCore/QCoreApplication> #include <Windows.h> #include <Winhttp.h> #include <QDebug> #pragma comment(lib, "Winhttp.lib") int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); HINTERNET hSession = WinHttpOpen(L"WinHttp Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if(!hSession) { qDebug() << "WinHttpOpen failed:" << GetLastError(); return 1; } HINTERNET hConnect = WinHttpConnect(hSession, L"example.com", INTERNET_DEFAULT_HTTPS_PORT, 0); if(!hConnect) { qDebug() << "WinHttpConnect failed:" << GetLastError(); WinHttpCloseHandle(hSession); return 1; } HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"POST", L"/", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if(!hRequest) { qDebug() << "WinHttpOpenRequest failed:" << GetLastError(); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return 1; } LPCWSTR headers = L"Content-Type: application/x-www-form-urlencoded\r\n"; LPCWSTR data = L"key1=value1&key2=value2"; DWORD dataLength = wcslen(data) * sizeof(WCHAR); BOOL bResult = WinHttpSendRequest(hRequest, headers, wcslen(headers), (LPVOID)data, dataLength, dataLength, 0); if(!bResult) { qDebug() << "WinHttpSendRequest failed:" << GetLastError(); WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return 1; } bResult = WinHttpReceiveResponse(hRequest, NULL); if(!bResult) { qDebug() << "WinHttpReceiveResponse failed:" << GetLastError(); WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return 1; } DWORD statusCode = 0; DWORD statusCodeSize = sizeof(DWORD); bResult = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &statusCode, &statusCodeSize, NULL); if(!bResult) { qDebug() << "WinHttpQueryHeaders failed:" << GetLastError(); } else { qDebug() << "Status code:" << statusCode; } QByteArray responseData; DWORD bytesRead = 0; DWORD bufferSize = 4096; LPBYTE buffer = new BYTE[bufferSize];
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值