C++/MFC簡單實現HTTP通信(基於CHttpFile)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章