c++ - 在 curl 和 c++ 中测量下载速度。我做得对吗?

标签 c++ curl

我想弄清楚如何在下载许多文件的文件夹(我正在下载的不是单个文件)时计算当前下载速度。而且我无法正确地做到这一点,现在经历了很多个小时,它变得太困惑了。下载速度有时过高,有时为 0。

我正在使用 curl 和 c++。

在我的下载函数中,程序递归地下载每个文件,直到所有文件都被下载。

这就是我设置 curl 以在下载期间调用 TraceProgress 函数的方式:

curl_easy_setopt( curl, CURLOPT_PROGRESSFUNCTION, TraceProgress );
curl_easy_setopt( curl, CURLOPT_PROGRESSDATA, &response );
curl_easy_setopt( curl, CURLOPT_NOPROGRESS, 0 );

这是剩余的代码:

    double totalDownloadableSize = 0; // total size of the download, set prior to starting download of the first file
    double downloadedSizeTillNow = 0; // total size downloaded till now - keep adding file size that just completed downloading
    double currentDownloadingSize = 0; // size that we are downloading - downloadedSizeTillNow + bytes downloaded of the current file (in TraceProgress Function)
    double oldDownloadNow = 0; // size of the old download bytes of that particular file


    string fileDownloading = "";
    string tempFileDownloading = "";

    time_t startSeconds;
    time_t oldSeconds;

    int downloadIterationCounter = 0;




    int TraceProgress( void *clientp, double dltotal, double dlnow, double ultotal, double ulnow )
    {

        // add size downloaded till now of this file to the total size downloaded till now
        currentDownloadingSize = downloadedSizeTillNow + dlnow;

        double rem = ( ( totalDownloadableSize - currentDownloadingSize ) / 1024 ) / 1024;

        // get current time in seconds
        time_t currentSeconds = time (NULL);

        // get elapsed time since last itiration
        time_t secondsElapsedSinceLastItiration = currentSeconds - oldSeconds;

        double downloadSinceLastIteration;
        if ( oldDownloadNow < dlnow )// so that we don't get wrong data when download file changes
        {
            downloadSinceLastIteration = dlnow - oldDownloadNow;
        }
        else
        {
            downloadSinceLastIteration = dlnow;
        }

        // calculate current download speed : (dlnow - oldNow) / (current time - oldTime)
        double currentDownloadSpeed = downloadSinceLastIteration / (double)secondsElapsedSinceLastItiration;


        // if downloading file name is not same as it was in the last call to this function
        // change the display text and save the name in the temp. This approach will avoid unnecessory
        // text change calls.
        if ( fileDownloading.compare( tempFileDownloading ) != 0 )
        {
             tempFileDownloading = fileDownloading;
             string dlfilename = "Downloading:  " + fileDownloading;
             SetWindowText( hDownloadingSTATIC, dlfilename.c_str() );// set text to static control
        }


        if ( downloadIterationCounter == 4 )
        {
             std::ostringstream strs_dn;
             strs_dn << (unsigned int)( rem );
             std::string downloadNow = strs_dn.str();


             string remSize = "Remaining:  " + downloadNow + " MB";
             SetWindowText( hRemainingDownloadSTATIC, remSize.c_str() );// set text to static control


             double idownloadSpeed = currentDownloadSpeed / 1024;

             std::ostringstream strs_dnSp;
             strs_dnSp << (unsigned int)( idownloadSpeed );
             std::string downloadSpeed = strs_dnSp.str();

             string downSize = "Download Speed:  " + downloadSpeed + " KB/s";
             SetWindowText( hDownloadSpeedSTATIC, downSize.c_str() );// set text to static control


             oldSeconds = currentSeconds;// save in old
             oldDownloadNow = dlnow;// save in old


             downloadIterationCounter = 0;
        }
        else
        {
             downloadIterationCounter++;
        }

        return 0;
    }

感谢任何帮助。非常感谢。

最佳答案

dlnow - oldDownloadNow 可能是错误的。您应该只使用 dlnow 代替。您根本不需要 oldDownloadNow,除非您想显示下载速度变化率

I was confused by the `dltotal` and `dlnow` names. `dltotal` is the *expected* total bytes downloaded, and `dlnow` is bytes downloaded so far. So one does need `oldDownloadNow`, and `dlnow - oldDownloadNow` is the current delta.

这个片段

    if ( oldDownloadNow < dlnow )
    {
        downloadSinceLastIteration = dlnow - oldDownloadNow;
    }
    else
    {
        downloadSinceLastIteration = dlnow;
    }

有一个错误:oldDownloadNow == dlnow 表示自上次以来没有下载任何内容。在这种情况下,当前的瞬时下载速度为零。该片段应替换为

    downloadSinceLastIteration = dlnow - oldDownloadNow;

没有任何检查。如果 libcurl 突然决定 oldDownloadNow > dlnow,这将适时显示负下载速度,这是正确的做法。永远不要故意隐藏错误。

此外,time() 分辨率太粗了。使用某种细粒度计时器。

关于c++ - 在 curl 和 c++ 中测量下载速度。我做得对吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13788943/

相关文章:

c++ - OpenCV/FFMpeg图像捕捉问题

c++ - 对 boost 库的 undefined reference

image - 如何获取网站中所有图片的所有信息

javascript - 使用 Mailchimp API 3.0 获取并显示成员(member)状态(或错误)

c++ - 对于具有一维常量的二维数组,使用 delete [] 进行内存释放

c++ - 可变参数模板、类型推导和 std::function

C#、C++ 项目组合 : Could not load file or assembly

node.js - nodejs https#request 在相同的 curl 请求成功的地方失败

php - PHP 执行 shell_exec 命令但不执行任何操作

java - 无法通过 java Runtime.getRuntime.exec() 发送 JSON 字符串;