在C++中使用Windows API發送HTTP GET請求


在網上找了很多文章,但基本都是說,C++發送HTTP請求可以,但談到具體方法,就眾說眾說紛紜了。具體說來,有IXMLHTTPRequest2、curl、POCO,當然還有用socket、Windows API的方法。這些方法中,除了socket外,我都嘗試過。

首先我用的是curl,需要先編譯,編譯完成后,就可以用curl_xxx的函數來發送和接收請求了,但是馬上我就發現了一個問題,必須使用動態鏈接庫才能運行,即使我編譯好了靜態庫,還指定了/MT(而不是/MD),也不行。非常的尷尬,本來應該是一個跨平台的完美解決方案,但就因為這樣一個愚蠢的原因,就沒探索了。

然后我嘗試使用COM組件,需要用到<MsXml6.h>頭文件和<MsXml6.lib>庫,網上有IXMLHTTPRequest2的例子,但例子是Windows Store上的應用,語法也是C++/CX,部分代碼還用到了.NET里面的東西(雖然我相信可以不需要.NET),移植了一陣子后,感覺很麻煩,就換方法了。

再然后我發現POCO庫可以解決這個問題,當准備用POCO庫的時候,發現也需要編譯,就想到了以前編譯curl和gmp后的結果(靜態庫總有這樣或那樣的問題,動態庫正常),然后直接沒信心再試了。

最后我使用了Windows API,用的<winhttp.h>頭文件,配合使用winhttp.lib庫,成功,而且感覺,只需封裝一下,這是我想要的方法:

// CppConsole.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include <winhttp.h>
#pragma comment(lib, "winhttp")

using namespace std;

void do_work();

int _tmain(int argc, _TCHAR* argv[])
{
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    do_work();
}

void do_work()
{
    DWORD dwSize = 0;
    DWORD dwDownloaded = 0;
    LPSTR pszOutBuffer;
    BOOL bResults = FALSE;
    HINTERNET hSession = NULL, 
              hConnect = NULL, 
              hRequest = NULL;

    // Use WinHttpOpen to obtain a session handle.
    hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", 
                           WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 
                           WINHTTP_NO_PROXY_NAME, 
                           WINHTTP_NO_PROXY_BYPASS, 0);

    // Specify an HTTP server
    if (hSession)
        hConnect = WinHttpConnect(hSession, L"baidu.com", 
                                  INTERNET_DEFAULT_HTTP_PORT, 0);

    // Create an HTTP Request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest(hConnect, L"GET", 
                                      L"", 
                                      NULL, WINHTTP_NO_REFERER, 
                                      WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                      0);

    // Send a Request.
    if (hRequest)
        bResults = WinHttpSendRequest(hRequest, 
                                      WINHTTP_NO_ADDITIONAL_HEADERS, 
                                      0, WINHTTP_NO_REQUEST_DATA, 0, 
                                      0, 0);

    // End the request.
    if (bResults)
        bResults = WinHttpReceiveResponse(hRequest, NULL);

    // Continue to verify data until there is nothing left.
    if (bResults)
    {
        do
        {
            // Verify available data.
            dwSize = 0;
            if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                printf("Error %u in WinHttpQueryDataAvailable.\n", 
                       GetLastError());
            
            // Allocate space for the buffer.
            pszOutBuffer = new char[dwSize+1];
            
            // Read the Data.
            ZeroMemory(pszOutBuffer, dwSize+1);

            if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer, 
                                 dwSize, &dwDownloaded))
                printf("Error %u in WinHttpReadData.\n", GetLastError());
            else
                printf("%s\n", pszOutBuffer);

            // Free the memory allocated to the buffer.
            delete[] pszOutBuffer;
        } while (dwSize > 0);
    } 

    // Report errors.
    if (!bResults)
        printf("Error %d has occurred.\n", GetLastError());

    // Close open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM