下载速度全面跳跃

问题描述 投票:0回答:1

我有一个小程序,使用curl从ftp下载文件。在CURLOPT_PROGRESSFUNCTION中传递的函数中,我做了计算以了解下载速度,问题是下载速度在整个地方跳跃,在2mbps互联网连接上从512kbps跳到8mbps。我无法确定这里有什么问题。

编辑:我已经更改了代码以平均读数,curl下载的问题是你无法预测何时调用TraceProgress函数,它可以在不到1秒内再次调用,所以程序等待5次迭代注意在读数之前,在平均之前取6个这样的读数,我还考虑了自上次读取以来经过的时间(秒),因为我们不能保证以相等的间隔调用TraceProgress函数。

如果现在看起来更好,请告诉我。

这是代码:

int minorCounter = 0;
int majorCounter = 0;

int minorCycle = 4;
int majorCycle = 5;

double blockDL[6];
double blockTime[6];

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

  if ( minorCounter == minorCycle )
    {

            blockDL[majorCounter] = dlnow - oldDownloadNow;

            myTimer.Tick();
            blockTime[majorCounter] = myTimer.GetDurationInSecs();

            minorCounter = 0;


            if ( majorCounter == majorCycle )
            {
                double dl = 0;
                double tm = 0;

                for ( int i = 0; i < majorCycle ; i++ )
                {
                    dl += blockDL[i];
                    tm += blockTime[i];
                }

                dl = dl/(majorCycle+1);

                tm = tm/(majorCycle+1);

                double currentDownloadSpeed = dl / tm;

                /* download speed - divide by 1024 to get speed in kilobytes instead of bytes */
                double idownloadSpeed = currentDownloadSpeed / 1024;

                string post;
                if ( idownloadSpeed > 1024 )
                {
                       idownloadSpeed = idownloadSpeed / 1024;
                       post = " MB/s";
                }
                else
                {
                        post = " KB/s";
                }

                string downloadSpeed = DoubleToString( idownloadSpeed );

                size_t x = downloadSpeed.find( "." );
                downloadSpeed.erase( x+2 );

                downSize = "Download Speed:  " + downloadSpeed + post;
                SendMessage( hDownloadSpeedSTATIC, WM_SETTEXT, (WPARAM)0, (LPARAM)downSize.c_str() );

                majorCounter = 0;
            }
            else
            {
                majorCounter++;
            }

            oldDownloadNow = dlnow;
            myTimer.Start();
    }
    else
    {
            minorCounter++;
    }

    return 0;
}
c++ winapi libcurl
1个回答
2
投票

你需要使用一个采样窗口和指数衰减或其他一些理智。

如果一辆汽车每隔30分钟从一条装配线上下来,而你只需要一个样品,就会发生可怕的事情。例如,如果您在汽车离线后立即采样,然后在20分钟后再次采样,您将在20分钟内看到零汽车,即每小时零汽车的速度。如果您在汽车下线之前进行采样,并在31分钟后再次进行采样,您将在31分钟内看到两辆汽车,每小时3.9辆汽车。

这是一个简单的算法:

  1. 保持单个计数和单个平均速度。从零开始它们。
  2. 每秒更新一次。
  3. 每秒,首先将计数加到前一秒中接收的字节数。
  4. 添加计数后,从计数中减去1/8的计数。 count -= (count/8);
  5. 将平滑的平均速度(以每秒位数数为单位)更新为当前计数。 bits_per_sec = count;

要了解此算法的工作原理,请假设计数是常量。这意味着添加到计数中的金额必须等于减去的金额。这意味着计数必须是每秒添加的字节数的8倍,使其成为每秒接收的位数。

© www.soinside.com 2019 - 2024. All rights reserved.