正在加载小宠物
梦回起点
做你害怕做的事,你会发现:不过如此
本站基于WordPress—主题by 设计窝 \n
冀ICP备15003737号
梦回起点
Copyright © 2015-2024 All rights reserved.

Wininet使用方法

微软貌似没有提供例子,这里提供简单的使用方法,这里是同步的访问,异步的方法可以看下微软的文档。

#include <stdio.h>
#include <Windows.h>
#include <wininet.h>
#include <string>
#include <map>
#include <vector>

#define USER_AGENT L"WinInetTestCode/1.0"

using namespace std;
//链接需要 wininet.lib
#pragma comment(lib,"wininet.lib")

std::vector<std::wstring> Split(const std::wstring& str, const std::wstring& delim)
{
    std::vector<std::wstring> result;
    size_t delim_len = delim.length();
    std::string::size_type pos1 = 0;
    std::string::size_type pos2 = str.find(delim);

    while (pos2 != std::string::npos)
    {
        result.emplace_back(str, pos1, pos2 - pos1);

        pos1 = pos2 + delim_len;
        pos2 = str.find(delim, pos1);
    }

    if (pos1 != str.length())
    {
        result.emplace_back(str, pos1);
    }

    return result;
}
std::wstring& Trim(std::wstring& s)
{
    if (s.empty())
    {
        return s;
    }

    s.erase(0, s.find_first_not_of(L" "));
    s.erase(s.find_last_not_of(L" ") + 1);
    s.erase(0, s.find_first_not_of(L"\t"));
    s.erase(s.find_last_not_of(L"\t") + 1);
    return s;
}
BOOL SendRequest(const std::wstring& strUrl,    //要访问的URL
    LPCWSTR lpMothod,    //方法 POST GET PUT ...
    LPBYTE lpData,      //数据
    DWORD dwSize,      //数据的大小
    const std::map<std::wstring, std::wstring>& mapInputHeaders,//发送的HTTP头
    DWORD& dwRetCode,   //返回的状态
    std::map<std::wstring, std::wstring>& mapOutputHeaders,//返回的HTTP头
    LPBYTE& lpRetData,//返回的数据Buffer指针,需要调用者使用delete[] 释放
    DWORD& dwRetSize) //返回的数据大小
{
    lpRetData = nullptr;
    dwRetSize = 0;
    if (nullptr == lpMothod) {
        return FALSE;
    }

    //0.解析URL,这里为了防止将栈空间用光,最好使用堆内存
    //测试代码,一切从简
    typedef struct URLDATA 
    {
        WCHAR szServerName[1024];
        WCHAR szObjectName[1024];
        WCHAR szScheme[64];
    }URLDATA,* PURLDATA;
    URLDATA urlData;
    PURLDATA pUrlData = &urlData;//new URLDATA;
    URL_COMPONENTSW urlParse = {0};
    urlParse.dwStructSize = sizeof(urlParse);
    urlParse.dwHostNameLength = sizeof(pUrlData->szServerName);
    urlParse.lpszHostName = pUrlData->szServerName;
    urlParse.lpszScheme = pUrlData->szScheme;
    urlParse.dwSchemeLength = sizeof(pUrlData->szScheme);
    urlParse.lpszUrlPath = pUrlData->szObjectName;
    urlParse.dwUrlPathLength = sizeof(pUrlData->szObjectName);
    if (!InternetCrackUrl(strUrl.c_str(), strUrl.length(),
        0, &urlParse))
    {
        return FALSE;
    }

    //1.初始化
    LPCTSTR lpszAgent = USER_AGENT;
    HINTERNET hInternet = InternetOpen(lpszAgent,
        INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    LPCTSTR lpszServerName = urlParse.lpszHostName;//"ssl.google-analytics.com"; //设置server
    INTERNET_PORT nServerPort = urlParse.nPort;//INTERNET_DEFAULT_HTTP_PORT;//INTERNET_DEFAULT_HTTPS_PORT; // HTTPS端口443
    DWORD dwConnectFlags = 0;
    DWORD dwConnectContext = 0;

    //2.连接
    HINTERNET hConnect = InternetConnect(hInternet,
        lpszServerName, nServerPort,
        NULL, NULL,
        INTERNET_SERVICE_HTTP,
        dwConnectFlags, dwConnectContext);

    //3.发送请求
    LPCTSTR lpszVerb = lpMothod;
    LPCTSTR lpszObjectName = urlParse.lpszUrlPath;
    LPCTSTR lpszVersion = NULL;    // 默认.
    LPCTSTR lpszReferrer = NULL;   // 没有引用页
    LPCTSTR* lplpszAcceptTypes = NULL; // Accpet所有类型.
    DWORD dwOpenRequestFlags = INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP |
        INTERNET_FLAG_KEEP_CONNECTION |
        INTERNET_FLAG_NO_AUTH |
        INTERNET_FLAG_NO_COOKIES |
        INTERNET_FLAG_NO_UI |
        //设置启用HTTPS
        INTERNET_FLAG_RELOAD;
    //处理HTTPS的情况
    if (urlParse.nScheme == INTERNET_SCHEME_HTTPS) {
        dwOpenRequestFlags |= INTERNET_FLAG_SECURE;
    }
    DWORD dwOpenRequestContext = 0;
    HINTERNET hRequest = HttpOpenRequest(hConnect, lpszVerb, lpszObjectName, lpszVersion,
        lpszReferrer, lplpszAcceptTypes,
        dwOpenRequestFlags, dwOpenRequestContext);

    for(std::map<std::wstring, std::wstring>::const_iterator itIndex = mapInputHeaders.begin();
        itIndex != mapInputHeaders.end(); itIndex++)
    {
        std::wstring strHeader = itIndex->first + L":" + itIndex->second;
        //设置HTTP头
        HttpAddRequestHeaders(hRequest, strHeader.c_str(), -1,HTTP_ADDREQ_FLAG_ADD| HTTP_ADDREQ_FLAG_REPLACE);
    }

    do {
        DWORD dwError = 0;
        if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0))
        {
            if (dwError == ERROR_INTERNET_INVALID_CA)
            {
                DWORD dwFlags;
                DWORD dwBuffLen = sizeof(dwFlags);
                InternetQueryOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS,
                    (LPVOID)&dwFlags, &dwBuffLen);

                dwFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
                InternetSetOption(hRequest, INTERNET_OPTION_SECURITY_FLAGS,
                    &dwFlags, sizeof(dwFlags));
                continue;
            }
        }
        break;
    } while (TRUE);

    //4.处理返回头数据
    //获得HTTP Response Header信息
    DWORD dwInfoLevel = HTTP_QUERY_RAW_HEADERS_CRLF;
    DWORD dwInfoBufferLength = 4094;
    PBYTE pInfoBuffer = new BYTE[dwInfoBufferLength+2];
    ZeroMemory(pInfoBuffer, dwInfoBufferLength);
    BOOL bRet = TRUE;
    while (!HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, pInfoBuffer, &dwInfoBufferLength, NULL)) {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            delete[] pInfoBuffer;
            pInfoBuffer = new BYTE[dwInfoBufferLength+2];
            ZeroMemory(pInfoBuffer, dwInfoBufferLength);
        }
        else {
            delete[] pInfoBuffer;
            return FALSE;
        }
    }
    pInfoBuffer[dwInfoBufferLength] = '\0';
    pInfoBuffer[dwInfoBufferLength+1] = '\0';
    //分割字符串把头放到返回的map中
    std::vector<std::wstring> vecHeaders = Split((PWCHAR)pInfoBuffer, L"\r\n");
    delete[] pInfoBuffer;

    for (std::vector<std::wstring>::iterator itIndex = vecHeaders.begin(); 
        itIndex != vecHeaders.end(); itIndex++)
    {
        if (std::wstring::npos != itIndex->find(L":")) {
            std::vector<std::wstring> vecItem = Split(*itIndex, L":");
            if (vecItem.size() > 1) {
                mapOutputHeaders.insert(std::make_pair(Trim(vecItem[0]), Trim(vecItem[1])));
            }
        }
    }

    //5.获取返回状态
    //HTTP_QUERY_STATUS_CODE
    dwInfoBufferLength = sizeof(dwRetCode);

    if (!HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwRetCode, &dwInfoBufferLength, NULL)) {
        dwRetCode = 0;
    }

   /* lpRetData = nullptr;
        dwRetSize = 0;*/
    //6.获取数据
    DWORD dwBytesAvailable = 0;
    while (InternetQueryDataAvailable(hRequest, &dwBytesAvailable, 0, 0)
        && dwBytesAvailable > 0) 
    {
        if (lpRetData) {
            LPBYTE lpBuffer = new BYTE[dwBytesAvailable + dwRetSize];
            CopyMemory(lpBuffer, lpRetData, dwRetSize);
            delete[] lpRetData;
            lpRetData = lpBuffer;
        }
        else {
            lpRetData = new BYTE[dwBytesAvailable];
        }
        if (!InternetReadFile(hRequest, lpRetData + dwRetSize,
            dwBytesAvailable, &dwBytesAvailable)) 
        {
            break;
        }
        dwRetSize += dwBytesAvailable;
        dwBytesAvailable = 0;
    }

    return TRUE;
}

int main(int argc, char* argv[])
{
    std::wstring strUrl = L"https://www.baidu.com";
    std::map<std::wstring, std::wstring> mapInputHeaders;
    std::map<std::wstring, std::wstring> mapOutputHeaders;
    mapInputHeaders.insert(std::make_pair(L"test-header", L"test"));
    DWORD dwRetCode;
    LPBYTE lpRetBuffer;
    DWORD dwRetSize;
    SendRequest(strUrl, L"GET", nullptr, 0, mapInputHeaders,
        dwRetCode, mapOutputHeaders, lpRetBuffer, dwRetSize
        );
    wprintf(L"%d\n", dwRetCode);
    for (std::map<std::wstring, std::wstring>::iterator itIndx = mapOutputHeaders.begin();
        itIndx != mapOutputHeaders.end(); itIndx++)
    {
        wprintf(L"%s:%s\n\n", itIndx->first.c_str(), itIndx->second.c_str());
    }

    printf("%s\n",lpRetBuffer);

    return 0;
}

搬了下面文章部分代码:
https://www.likecs.com/show-985928.html
https://www.cnblogs.com/demon90s/p/15612975.html

2022-04-17
暂无评论

发表回复