|  | 
 
| 要在 VC++ 客户端中统计下载的网速,可以在下载过程中记录已下载的字节数和所用的时间。可以使用 `std::chrono` 库来测量时间,并在每次读取数据后计算当前的下载速度。 
 以下是修改后的代码示例,添加了下载速度的统计功能:
 
 复制代码
```cpp
#include <windows.h>
#include <winhttp.h>
#include <iostream>
#include <fstream>
#include <chrono>
#include <thread>
#pragma comment(lib, "winhttp.lib")
void DownloadFile(const std::wstring& server, const std::wstring& filePath, const std::wstring& savePath, int speedLimit) {
    HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", 
                                     WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                     WINHTTP_NO_PROXY_NAME, 
                                     WINHTTP_NO_PROXY_BYPASS, 0);
    if (!hSession) {
        std::cerr << "WinHttpOpen failed." << std::endl;
        return;
    }
    HINTERNET hConnect = WinHttpConnect(hSession, server.c_str(), INTERNET_DEFAULT_HTTP_PORT, 0);
    if (!hConnect) {
        std::cerr << "WinHttpConnect failed." << std::endl;
        WinHttpCloseHandle(hSession);
        return;
    }
    HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", filePath.c_str(), 
                                            NULL, WINHTTP_NO_REFERER, 
                                            WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
    
    if (!hRequest) {
        std::cerr << "WinHttpOpenRequest failed." << std::endl;
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return;
    }
    // 发送请求
    if (!WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, 
                            WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) {
        std::cerr << "WinHttpSendRequest failed." << std::endl;
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return;
    }
    // 等待响应
    if (!WinHttpReceiveResponse(hRequest, NULL)) {
        std::cerr << "WinHttpReceiveResponse failed." << std::endl;
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return;
    }
    // 打开文件以写入
    std::ofstream outFile(savePath, std::ios::binary);
    if (!outFile.is_open()) {
        std::cerr << "Failed to open file for writing." << std::endl;
        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);
        return;
    }
    // 读取数据并写入文件
    DWORD bytesRead;
    char buffer[4096]; // 4KB 缓冲区
    long long totalBytesRead = 0; // 总共读取的字节数
    auto startTime = std::chrono::high_resolution_clock::now(); // 开始时间
    while (true) {
        if (!WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead) || bytesRead == 0) {
            break; // 读取完成或出错
        }
        outFile.write(buffer, bytesRead);
        totalBytesRead += bytesRead;
        // 限制速度
        std::this_thread::sleep_for(std::chrono::milliseconds(1000 * bytesRead / speedLimit)); // 限速
        // 计算并输出下载速度
        auto currentTime = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double> elapsed = currentTime - startTime;
        if (elapsed.count() > 0) {
            double speed = (totalBytesRead / 1024.0) / elapsed.count(); // KB/s
            std::cout << "当前下载速度: " << speed << " KB/s" << std::endl;
        }
    }
    // 关闭文件
    outFile.close();
    // 清理
    WinHttpCloseHandle(hRequest);
    WinHttpCloseHandle(hConnect);
    WinHttpCloseHandle(hSession);
    std::cout << "文件下载成功: " << savePath << std::endl;
}
int main() {
    std::wstring server = L"localhost"; // 替换为你的服务器地址
    std::wstring filePath = L"/download"; // 替换为下载路径
    std::wstring savePath = L"C:\\path\\to\\save\\file.zip"; // 替换为保存路径
    int speedLimit = 50 * 1024; // 限制速度为 50 KB/s
    DownloadFile(server, filePath, savePath, speedLimit);
    return 0;
}
```
 
 ### 代码说明
 
 1. **总字节数**:使用 `long long totalBytesRead` 变量来跟踪已读取的总字节数。
 2. **开始时间**:在开始下载时记录开始时间。
 3. **计算速度**:在每次读取数据后,计算经过的时间,并根据已读取的字节数计算下载速度(单位为 KB/s)。
 4. **输出速度**:在控制台输出当前下载速度。
 
 ### 注意事项
 
 - 你可以根据需要调整限速值。
 - 计算速度的逻辑可以根据需要进行优化,例如每隔一定时间输出一次速度,而不是每次读取数据后都输出。
 
 通过这种方式,你可以在下载过程中实时监控下载速度。
 
 
 
 | 
 |