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

C++ 在curl和c+中测量下载速度+;。我做得对吗?,c++,curl,C++,Curl,我试图找出如何计算当前下载速度,而下载文件夹的许多文件(它不是一个单一的文件,我下载)。我不能正确地做这件事,现在我花了好几个小时,它变得太混乱了。下载速度有时过高,有时为0 我使用卷曲和C++。< /P> 在我的下载函数中,程序递归地下载每个文件,直到所有文件都被下载 这是我如何设置curl以在下载期间调用TraceProgress函数的: curl_easy_setopt( curl, CURLOPT_PROGRESSFUNCTION, TraceProgress ); curl_easy_

我试图找出如何计算当前下载速度,而下载文件夹的许多文件(它不是一个单一的文件,我下载)。我不能正确地做这件事,现在我花了好几个小时,它变得太混乱了。下载速度有时过高,有时为0

我使用卷曲和C++。< /P> 在我的下载函数中,程序递归地下载每个文件,直到所有文件都被下载

这是我如何设置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;
    }
double totalDownloadableSize=0;//下载的总大小,在开始下载第一个文件之前设置
双下载SizeTillNow=0;//到目前为止下载的总大小-继续添加刚完成下载的文件大小
double currentDownloadingSize=0;//我们正在下载的大小-downloadedSizeTillNow+当前文件的下载字节数(在TraceProgress函数中)
double oldDownloadNow=0;//该特定文件的旧下载字节的大小
字符串fileDownloading=“”;
字符串tempFileDownloading=“”;
时间开始秒;
时间(秒);
int downloadIterationCounter=0;
int TraceProgress(void*clientp,双dltotal,双dlnow,双ultotal,双ulnow)
{
//将此文件的下载到现在的大小添加到下载到现在的总大小
currentDownloadingSize=downloadedSizeTillNow+dlnow;
双rem=((totalDownloadableSize-currentDownloadingSize)/1024)/1024;
//以秒为单位获取当前时间
时间\u t currentSeconds=时间(空);
//获取自上次初始化以来经过的时间
time\u t SecondSelapsedSincellation=当前秒数-旧秒数;
两次下载一次;
if(oldDownloadNowdlnow-oldDownloadNow
可能是错误的。您应该只使用
dlnow
。您根本不需要
oldDownloadNow
,除非您想显示下载速度的变化率

我被'dltotal'和'dlnow'的名称弄糊涂了。'dltotal'是下载的*预期*总字节数,'dlnow'是到目前为止下载的字节数。因此确实需要'oldDownloadNow','dlnow-oldDownloadNow'是当前的增量。 这个片段

    if ( oldDownloadNow < dlnow )
    {
        downloadSinceLastIteration = dlnow - oldDownloadNow;
    }
    else
    {
        downloadSinceLastIteration = dlnow;
    }
没有任何检查。如果
libcurl
突然决定
oldDownloadNow>dlnow
,这将适时显示负下载速度,这是正确的做法。切勿故意隐藏错误


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

似乎您正在编写一个GUI程序-我认为除了主线程之外,从任何地方更新UI都不是最好的主意。也许这就是我遇到奇怪图形错误的原因,例如应用程序的外观变为空白灰色?:o您建议正确的方法是什么?下载需要在单独的线程中。为什么不要求
pthread\u main()
这样做(只更新UI)?当下载在一个单独的线程中进行时,我该怎么做?在主线程中下载意味着没有刷新。这是一个很好的观点,如果oldDownloadNow==dlnow,那么DownloadSincellation=dlnow-oldDownloadNow;将意味着DownloadSincellation=0;随后的下载速度将达到0。可能应该有一个c检查oldDownloadNow==dlnow,在这种情况下什么都不做?为了检查文件更改问题,我在开始下一个文件下载之前将oldDownloadNow设置为0,因为有一段时间,最后一个文件刚下载,oldDownloadNow设置为更高的值,而新文件的dlnow则低得多,听起来不错吗ng?为什么?当前的下载速度是0,请像其他速度一样报告。在文件更改情况下,您的解决方案听起来是正确的,但您可能想测试它。是的,您是对的,我没有这样看..嗯…最后一个帮助,如果您愿意,您能帮我解决上面提到的关于从非主线程更新UI的@H2CO3问题吗?谢谢谢谢。对不起,我对Windows线程或GUI API不太熟悉。
    downloadSinceLastIteration = dlnow - oldDownloadNow;