C++ http请求

代码中使用TCHAR当参数是为了方便支持unicode和ansi,使用string当返回值是因为web返回的一般都是utf8字符,所以最好在加一个utf82gbk接口转换,可能还要加s2cs转cstring或者unicode。

CommonLog是我自己的接口,可以忽略

#include <WinInet.h>

#pragma comment(lib, "Wininet.lib")



string HttpRequest(const TCHAR * lpHostName, const TCHAR * lpUrl, const TCHAR * lpMethod, short sPort=80, char * lpPostData=NULL, int nPostDataLen=0);

string HttpRequest(const TCHAR * lpHostName, const TCHAR * lpUrl, const TCHAR * lpMethod, short sPort, char * lpPostData, int nPostDataLen)
{
	HINTERNET hInternet = NULL, hConnect = NULL, hRequest = NULL;

	TCHAR headerContentType[] = _T("Content-Type:application/x-www-form-urlencoded");
	TCHAR headAccept[] = _T("Accept: application/json, text/plain, */*");
	DWORD dwLastError = 0;
	BOOL bRet;

	std::string strResponse;

	hInternet = (HINSTANCE)InternetOpen(_T("User-Agent"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if (!hInternet)
	{
		CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("InternetOpen user-agent failed"));
		goto end;
	}

	//hostname可以写www.baidu.com,不能写http://www.baidu.com,
	hConnect = (HINSTANCE)InternetConnect(hInternet, lpHostName, sPort, NULL, _T("HTTP/1.1"), INTERNET_SERVICE_HTTP, 0, 0);
	if (!hConnect)
	{
		CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("InternetConnect failed"));
		goto end;
	}

	hRequest = (HINSTANCE)HttpOpenRequest(hConnect, lpMethod, lpUrl, _T("HTTP/1.1"), NULL, NULL, INTERNET_FLAG_RELOAD, 0);
	if (!hRequest)
	{
		CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpOpenRequest failed"));
		goto end;
	}
	///header可以加其他的///
	//_tcslen(headerContentType)千万不要因为以前养成的好习惯而加上*sizeof(TCHAR),不然header中会有乱码,看起来是length表示的是utf-8的长度,不是占用的字节数
	//nginx可能会报400
	bRet = HttpAddRequestHeaders(hRequest, headerContentType,_tcslen(headerContentType),HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
	if(!bRet)
	{
		CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpAddRequestHeaders failed"));
		goto end;
	}

	bRet = HttpAddRequestHeaders(hRequest, headAccept,_tcslen(headAccept),HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
	if(!bRet)
	{
		CommonLog::getInstance()->WriteLog(LogLevel_debug, _T("HttpAddRequestHeaders2 failed"));
		goto end;
	}
	

	bRet = HttpSendRequest(hRequest, NULL, 0, lpPostData, nPostDataLen);
	dwLastError = GetLastError();
	// 1个小bug,不要再写日志的的地方把GetLastError()当参数,可能日志打开文件也会报错183(重复打开已经存在的文件)

	while (TRUE)
	{
		char cReadBuffer[4096];
		unsigned long lNumberOfBytesRead;
		bRet = InternetReadFile(hRequest, cReadBuffer, sizeof(cReadBuffer) - 1, &lNumberOfBytesRead);
		if (!bRet || !lNumberOfBytesRead)
		{
			break;
		}
		cReadBuffer[lNumberOfBytesRead] = 0;
		strResponse = strResponse + cReadBuffer;
	}

end:
	if (hRequest)
		InternetCloseHandle(hRequest);
	if (hConnect)
		InternetCloseHandle(hConnect);
	if (hInternet)
		InternetCloseHandle(hInternet);

	return strResponse;
}

实例:

string res = HttpRequest(_T("www.test.com"), _T("/test/testReply"),
		_T("get"));

错误:

hostname中加http会报错

GetLastError最好放在函数调用后的第一行代码,不要再函数和函数后面的GetLastError中加入自己的代码,哪怕自己的代码不主动报错,切记不要把GetLastError()当参数,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值