本例介绍一下用MFC中的CHttpFile来简单的实现Http通信,简单有效。
源码:
HttpTools.h
#pragma once
#include <iostream>
#include "afxinet.h"
namespace HttpTools
{
enum HttpResult
{
HTTP_SUCCESS = 0, //成功
HTTP_FAILURE = 1, //失败
HTTP_OUTTIME = 2, //超时
};
enum HttpConnectType
{
NORMAL_CONNECT = INTERNET_FLAG_KEEP_CONNECTION, //http
SECURE_CONNECT = NORMAL_CONNECT | INTERNET_FLAG_SECURE, //https
};
enum HttpRequestType
{
NORMAL_REQUEST = INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, //http
SECURE_REQUEST = NORMAL_REQUEST | INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID, //https
};
static const wchar_t* IE_AGENT = L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)";
//使用CHttpFile来实现的http请求功能。
int HttpRequest(const std::wstring& strMethod, //get or post
const std::wstring& strUrl, //请求地址
const std::wstring& postData, //发送的数据
std::wstring& response, //回复
const std::wstring& strAgent = IE_AGENT //agent 默认是IE (IE_AGENT)
);
};
HttpTools.cpp
#include "StdAfx.h"
#include "HttpTools.h"
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");
//pHttpFile->AddRequestHeaders(L"Accept-Encoding: gzip, deflate");
//发送请求
pHttpFile->SendRequest(NULL, 0, (LPVOID)postData.data(), postData.length() * sizeof(wchar_t));
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);
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;
}
使用方式:
std::wstring rsp;
std::wstring rq = L"https://www.csdn.net";
HttpTools::HttpRequest(L"get",L"http://go.5211game.com/?", rq , rsp);