• 在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
  • 相关阅读:
    UIWebView 设置字体样式和行间距
    UIAlertView问题
    仿jquery的函数
    css 不换行,换行
    兼容火狐插入背景音乐
    防止屏蔽window.onload函数
    mysql
    解决手机浏览器上input 输入框导致页面放大的问题
    vue 中监听页面滚动
    WCF处理异常的方式
  • 原文地址:https://www.cnblogs.com/sdflysha/p/3135449.html
Copyright © 2020-2023  润新知