C++ wininet 以 513 字节块的形式获取数据

C++ wininet fetching data in 513 byte chunks

我正在尝试使用 wininet 获取我的服务器 html 文本数据,但它似乎正在读取它并将其分成 513 字节大小的块。但是,我更希望将数据作为一个整体来获取。我有办法解决这个问题吗?

完整代码供参考:

#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <iostream>
using namespace std;

#pragma comment (lib, "Wininet.lib")

int main(int argc, char** argv) {

    HINTERNET hSession = InternetOpen(L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    HINTERNET hConnect = InternetConnect(hSession, L"www.google.com", 0, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    HINTERNET hHttpFile = HttpOpenRequest(hConnect, L"GET", L"/", NULL, NULL, NULL, 0, 0);

    while (!HttpSendRequest(hHttpFile, NULL, 0, 0, 0)) {
        printf("Server Down..  (%lu)\n", GetLastError());

        InternetErrorDlg(GetDesktopWindow(), hHttpFile, ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, FLAGS_ERROR_UI_FILTER_FOR_ERRORS | FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, NULL);
    }

    DWORD dwFileSize;
    dwFileSize = BUFSIZ;

    char* buffer;
    buffer = new char[dwFileSize + 1];

    while (true) {
        DWORD dwBytesRead;
        BOOL bRead;
        bRead = InternetReadFile(hHttpFile, buffer, dwFileSize + 1, &dwBytesRead);
        if (dwBytesRead == 0) break;
        if (!bRead) {
            printf("InternetReadFile error : <%lu>\n", GetLastError());
        }
        else {
            buffer[dwBytesRead] = 0;

            std::string newbuff = buffer;

            std::wcout << "\n\nSize: " << newbuff.size() << std::endl;
            std::cout << newbuff; 

        }
    }

    InternetCloseHandle(hHttpFile);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);
}
dwFileSize = BUFSIZ;

如果您查看头文件,您会发现 BUFSIZ#defined 为 512。

buffer = new char[dwFileSize + 1];

// ...

Read = InternetReadFile(hHttpFile, buffer, dwFileSize + 1, &dwBytesRead);

然后您的程序继续分配 513 字节的缓冲区,然后读取输入,一次 513 字节。这正是您观察到的结果。这是显示的代码唯一知道如何做的事情。

如果你想使用更大的缓冲区大小,你可以很容易地改变它(并且没有理由 new 缓冲区无论如何,所做的只是创造内存泄漏的机会,只需使用 std::vector,或用于这种大小的较小缓冲区的普通数组)。

除非您事先知道要检索的文件的大小,否则您别无选择,只能分段读取文件,就像那样。尽管它是分段检索的,但看起来文件是在单个请求中检索的,只是显示的代码一次检索一个块,这非常好。切换到较大的缓冲区大小可能会提高性能,但不会显着。