WinHttp 接收数据代码

本文介绍了一个基于WinHTTP的C/C++实现的HTTP数据抓取函数,详细展示了如何构造HTTP请求,处理HTTPS连接,以及从响应中读取数据的过程。通过WinHttpOpen,WinHttpConnect,WinHttpOpenRequest等API的使用,实现了对指定URL的GET请求,并返回了数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef struct tagXYWINHTTP
{
    LPCTSTR proxy;
    LPCWSTR username;
    LPCTSTR password;
    LPCWSTR useragent;    // _T("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)")
    LPCWSTR servername;
    INTERNET_PORT serverport;    // INTERNET_DEFAULT_HTTP_PORT
    WCHAR verb[24];
    LPCWSTR objectname;    // 可以为 NULL
    LPCWSTR version;    // 可以为 NULL
    // 
    // WINHTTP_FLAG_SECURE
    DWORD flags;
    // WINHTTP_NO_ADDITIONAL_HEADERS
    LPCTSTR headers;
    DWORD headerslength;
    LPVOID parameter;
    DWORD post_timeout0;
    DWORD post_timeout1;
    DWORD get_timeout0;
    DWORD get_timeout1;
}XYWINHTTP, *PXYWINHTTP;
XYWINHTTP usc = { 0 };
VOID XYWinHttpInitialize(PXYWINHTTP pwh)
{
    pwh->useragent = NULL;
    pwh->serverport = INTERNET_DEFAULT_HTTPS_PORT;
    pwh->verb[0] = L'G';
    pwh->verb[1] = L'E';
    pwh->verb[2] = L'T';
    pwh->verb[3] = L'\0';
    pwh->objectname = NULL;
    pwh->version = NULL;
    pwh->flags = 0;
    pwh->headers = WINHTTP_NO_ADDITIONAL_HEADERS;
    pwh->headerslength = 0;
}
BYTE *XYWinHttpGetData(PXYWINHTTP pwh, DWORD *returnedsize, LPVOID poptional, DWORD optionallength, DWORD totallength)
{
    //DWORD value;
    DWORD numberofbytes;
    DWORD datasize;
    HINTERNET hsession;
    HINTERNET hconnect;
    HINTERNET hrequest;
    BYTE *result = NULL;
    BYTE *buffer;
    UINT size;
    UINT offset;

    *returnedsize = 0;

    hsession = WinHttpOpen(pwh->useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
    if (hsession != NULL)
    {
        //if (WinHttpQueryOption(hsession, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &datasize))
        {
            ;//OpenHttpOpen() error
        }
        hconnect = WinHttpConnect(hsession, pwh->servername, pwh->serverport, 0);//servername:域名 serverport:端口
        if (hconnect != NULL)
        {
            hrequest = WinHttpOpenRequest(hconnect, pwh->verb, pwh->objectname, pwh->version, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, pwh->flags);
            //headle,"GET",url,"HTTP/1.1",
            //verb:请求类型        objectname:整体信息的内容    version:HTTP/1.1  flags:是否使用https
            if (hrequest != NULL)
            {
                // Send a request.
                // WINHTTP_NO_REQUEST_DATA
                //poptional == WINHTTP_NO_REQUEST_DATA;
                //totallength == WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH;

                DWORD dwFlags =
                    SECURITY_FLAG_IGNORE_UNKNOWN_CA |
                    SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE |
                    SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
                    SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;

                if (WinHttpSetOption(
                    hrequest,
                    WINHTTP_OPTION_SECURITY_FLAGS,
                    &dwFlags,
                    sizeof(dwFlags)))
                {
                    //retry = true;
                }
                if (WinHttpSendRequest(hrequest, NULL, pwh->headerslength, poptional, optionallength, totallength, 0))
                    //handle,
                {
                    if (WinHttpReceiveResponse(hrequest, NULL))
                    {
                        offset = 0;
                        size = 0;
                        BOOL flag;
                        //检查可用的数据
                        while ((flag = WinHttpQueryDataAvailable(hrequest, &datasize)) && datasize > 0)
                        {
                            buffer = NULL;
                            if (offset + datasize > size)
                            {
                                size = (offset + datasize + 0xffff) >> 16;
                                size <<= 16;
                                buffer = (BYTE *)MALLOC(size);
                                if (buffer != NULL)
                                {
                                    if (offset > 0)
                                    {
                                        CopyMemory(buffer, result, offset);
                                        FREE(result);
                                    }
                                }
                            }
                            else
                            {
                                buffer = result;
                            }
                            if (buffer != NULL)
                            {
                                result = buffer;

                                if (WinHttpReadData(hrequest, (LPVOID)(result + offset), datasize, &numberofbytes) && numberofbytes > 0)
                                {
                                    offset += numberofbytes;
                                }
                                else
                                {
                                    buffer = NULL;
                                }
                            }
                            if (buffer == NULL)
                            {
                                break;
                            }
                        }

                        if (result != NULL)
                        {
                            if (!flag || datasize > 0)
                            {
                                FREE(result);
                                result = NULL;
                            }

                            if (result != NULL)
                            {
                                *returnedsize = offset;
                            }
                        }
                    }
                }

                WinHttpCloseHandle(hrequest);
            }

            WinHttpCloseHandle(hconnect);
        }

        WinHttpCloseHandle(hsession);
    }

    return(result);
}
BYTE *HttpGetData(PXYWINHTTP pwh, DWORD *returnedsize, LPCWSTR url)
{
    URL_COMPONENTS ucs;
    WCHAR hostname[256] = L"\0";
    DWORD hostnamelength;
    WCHAR urlpath[1024] = L"\0";
    DWORD urlpathlength;
    BYTE *result = NULL;
    // Initialize the URL_COMPONENTS structure.
    ZeroMemory(&ucs, sizeof(ucs));//初始化一个URL_COMPONENTS结构体
    ucs.dwStructSize = sizeof(ucs);//设置其中dwStructSize为结构体长度

    // 设置几个必要的项的初始值为非零。
    // 然后拆开url的整体,获取其中的许多小段的内容。
    ucs.dwSchemeLength = (DWORD)-1;
    ucs.dwHostNameLength = (DWORD)-1;
    ucs.dwUrlPathLength = (DWORD)-1;
    ucs.dwExtraInfoLength = (DWORD)-1;
    ucs.dwUserNameLength = (DWORD)-1;
    ucs.dwPasswordLength = (DWORD)-1;
    // Crack the URL.

    if (WinHttpCrackUrl(url, (DWORD)wcslen(url), 0, &ucs))
    {
        hostnamelength = 0;//主机名长度
        if (ucs.dwHostNameLength != (DWORD)-1 && hostnamelength + ucs.dwHostNameLength < sizeof(hostname) / sizeof(WCHAR))
        {
            memcpy(hostname + hostnamelength, ucs.lpszHostName, ucs.dwHostNameLength * sizeof(WCHAR));//写入主机名字符串
            hostnamelength += ucs.dwHostNameLength;
        }
        hostname[hostnamelength] = L'\0';

        urlpathlength = 0;//url字符串指针
        if (ucs.dwUrlPathLength != (DWORD)-1 && urlpathlength + ucs.dwUrlPathLength < sizeof(urlpath) / sizeof(WCHAR))
        {
            memcpy(urlpath + urlpathlength, ucs.lpszUrlPath, ucs.dwUrlPathLength * sizeof(WCHAR));
            urlpathlength += ucs.dwUrlPathLength;
        }
        if (ucs.dwExtraInfoLength != (DWORD)-1 && urlpathlength + 1 + ucs.dwExtraInfoLength < sizeof(urlpath) / sizeof(WCHAR))//加上附加信息
        {
            //urlpath[urlpathlength++] = L'?';
            memcpy(urlpath + urlpathlength, ucs.lpszExtraInfo, ucs.dwExtraInfoLength * sizeof(WCHAR));
            urlpathlength += ucs.dwExtraInfoLength;
        }
        urlpath[urlpathlength] = L'\0';

        if (hostnamelength > 0 && urlpathlength > 0)
        {
            pwh->useragent = L"Mozilla/6.0";

            pwh->servername = hostname;
            pwh->serverport = ucs.nPort;

            pwh->objectname = urlpath;
            pwh->flags = 0;
            switch (ucs.nScheme)
            {
            case INTERNET_SCHEME_HTTP:
                break;
            case INTERNET_SCHEME_HTTPS:
                pwh->flags |= WINHTTP_FLAG_SECURE;
                break;
            default:
                break;
            }

            result = XYWinHttpGetData(pwh, returnedsize, NULL, 0, 0);
        }
    }

    return(result);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值