这里仅仅是我的开发的一点经验,
C++通过httppost实现接口信息交互。
准备
c++调用httppost方法实现报文转发接收之前的准备工作,先通过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格式,所以发送的报文和接收的报文需要做处理,不然返回数据为乱码,或者发送报文数据不正确。