|
要在 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. **输出速度**:在控制台输出当前下载速度。
### 注意事项
- 你可以根据需要调整限速值。
- 计算速度的逻辑可以根据需要进行优化,例如每隔一定时间输出一次速度,而不是每次读取数据后都输出。
通过这种方式,你可以在下载过程中实时监控下载速度。
|
|