从互联网下载文件,HttpSendRequest失败,错误代码

时间:2013-12-22 06:03:33

标签: c++ windows

我正在创建一个可以从互联网上下载文件的程序。 在我下载文件之前,我想获取文件大小,我尝试过InternetQueryDataAvailable,但它的值为0.

然后我尝试了hHttpRequest,但它提供了错误代码ERROR_HTTP_HEADER_NOT_FOUND。所以我添加了HttpSendRequest,但它给出了错误代码ERROR_INTERNET_INVALID_URL。

我正在使用avg网站作为测试网站: http://free.avg.com/us-en/download-free-all-product

要下载的文件: avg_free_x86_all_2014_4259a6848.exe

任何帮助都会很好,谢谢。

代码:

DWORD DownloadFile(PCHAR SaveDirectory)
{
HINTERNET hInternet;
CHAR StrBuffer[100];

hInternet = InternetOpen(InternetAgent, PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0);
if (hInternet != NULL)
{
    CHAR TestUrl[] = "http://download.avgfree.com/filedir/inst";
    CHAR TestFileName[] = "avg_free_x86_all_2014_4259a6848.exe";

    HINTERNET hHttpSession = InternetConnect(hInternet, TestUrl, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
    if (hHttpSession != NULL)
    {
        PCTSTR AcceptTypes[] = {"text/*", "application/exe", "application/zlib", "application/gzip", "application/applefile", NULL};
        //I dont think application/exe is valid, but i could Not find a .exe format in the msdn list.
        //http://www.iana.org/assignments/media-types/media-types.xhtml#application for the list

        HINTERNET hHttpRequest = HttpOpenRequest(hHttpSession, "GET", TestFileName, "HTTP/1.1", TestUrl, &AcceptTypes[0],
            INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_RELOAD|INTERNET_FLAG_DONT_CACHE, 0);

        if (hHttpRequest != NULL)
        {
            DWORD FileSize = 0;
            DWORD BufferLength = sizeof(FileSize);

            if (HttpSendRequest(hHttpRequest, NULL, 0, NULL, 0))
            {
                //See if HttpQueryInfo can get the file size.
                if (HttpQueryInfo(hHttpRequest, HTTP_QUERY_CONTENT_LENGTH, &FileSize, &BufferLength, NULL))
                {
                    sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", FileSize);
                    MessageBox(MainWinHwnd, StrBuffer, "File Size", MB_OK);
                }
                else MessageBox(MainWinHwnd, "Failed to get the file size.", NULL, MB_OK);

                //See if InternetQueryDataAvailable can get the file size.
                if (InternetQueryDataAvailable(hHttpRequest, &FileSize, 0, 0))
                {
                    sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", FileSize);
                    MessageBox(MainWinHwnd, StrBuffer, "File Size", MB_OK);
                }
                else
                {
                    MessageBox(MainWinHwnd, "Failed to get the file size.", NULL, MB_OK);
                }
            }
            else
            {
                DWORD LastError = GetLastError();
                sprintf_s(StrBuffer, sizeof(StrBuffer), "%u", LastError);
                MessageBox(NULL, StrBuffer, NULL, MB_OK);
            }
            InternetCloseHandle(hHttpRequest);
        }
        else MessageBox(NULL, "Error #3", NULL, MB_OK);
        InternetCloseHandle(hHttpSession);
    }
    else MessageBox(NULL, "Error #2", NULL, MB_OK);
    InternetCloseHandle(hInternet);
}
else MessageBox(NULL, "Error #1", NULL, MB_OK);

return TRUE;
}

1 个答案:

答案 0 :(得分:4)

调用InternetConnect()时,仅为主机名指定"download.avgfree.com",而不是URL。

调用HttpOpenRequest()时,请指定"/filedir/inst/avg_free_x86_all_2014_4259a6848.exe"作为要请求的对象,而不是文件名。

使用InternetCrackUrl()将完整网址划分为各个组件,将lpszHostNamenPort字段传递到InternetConnect(),将lpszUrlPath字段传递给{{ 1}}。

您也无需知道文件大小即可下载。事实上,有时下载开始时不知道文件大小。有时会有。无论哪种方式,您只需在循环中调用HttpOpenRequest(),直到它报告无法接收更多数据。让它在内部为您处理文件大小。

BTW,看一下URLDownloadToFile()函数。让它为您处理这些细节。