本例介紹一下用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);