c++ - 从 Internet 下载文件,HttpSendRequest 失败并显示错误代码

标签 c++ windows

我正在创建一个可以从 Internet 下载文件的程序。 在下载文件之前,我想获取文件大小,我已经尝试过 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;
}

最佳答案

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

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

使用InternetCrackUrl()将完整的 URL 分成各个部分,将 lpszHostNamenPort 字段传递给 InternetConnect()lpszUrlPath 字段到 HttpOpenRequest()

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

顺便说一句,看看URLDownloadToFile()功能。让它为您处理这些细节。

关于c++ - 从 Internet 下载文件,HttpSendRequest 失败并显示错误代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20726723/

相关文章:

windows - PATH 环境如何影响我正在运行的可执行文件,从使用 msvcr90 到 msvcr80?

node.js - Node JS 中的最佳项目方法

python - 自动执行重复的键盘操作

c++ - 从链表的结构部分写入二进制文件

c++ - "Cannot overload functions distinguished by return type alone"是什么意思?

c++ - 为什么我可以分配一个长度小于数组本身的字符串文字?

c++ - 无法从注册表中读取字符串

c++ - 在 C++ 中,什么样的语句不需要分号终止?

windows - 导航到页面会增加内存使用量 Windows Universal 8.1

php - MySQL 数据库应使用什么数据类型来存储 2 个代码文本文件。如果我打算稍后比较相似度