【问题标题】:Calculate upload transfer speed problem计算上传传输速度问题
【发布时间】:2009-11-09 11:23:34
【问题描述】:

我已经实现了一个文件传输率计算器来显示我的应用程序中发生的上传过程的 kB/sec,但是使用以下代码,我似乎在文件开始后的 KB/s 读数中出现“突发”上传。

这是我的流代码的一部分,它使用 httpWebRequest 将 1024 个块的文件流式传输到服务器:

using (Stream httpWebRequestStream = httpWebRequest.GetRequestStream())
{
    if (request.DataStream != null)
    {
        byte[] buffer = new byte[1024];
        int bytesRead = 0;

        Debug.WriteLine("File Start");
        var duration = new Stopwatch();
        duration.Start();
        while (true)
        {
            bytesRead = request.DataStream.Read(buffer, 0, buffer.Length);
            if (bytesRead == 0)
                break;

            httpWebRequestStream.Write(buffer, 0, bytesRead);
            totalBytes += bytesRead;


            double bytesPerSecond = 0;
            if (duration.Elapsed.TotalSeconds > 0)
                bytesPerSecond = (totalBytes / duration.Elapsed.TotalSeconds);

            Debug.WriteLine(((long)bytesPerSecond).FormatAsFileSize());
        }
        duration.Stop();
        Debug.WriteLine("File End");
        request.DataStream.Close();
    }
}

现在上传过程的输出日志和相关的 kB/sec 读数如下: (您会注意到一个新文件以“文件开始”和“文件结束”开始和结束)

File Start
5.19 MB
7.89 MB
9.35 MB
11.12 MB
12.2 MB
13.13 MB
13.84 MB
14.42 MB
41.97 kB
37.44 kB
41.17 kB
37.68 kB
40.81 kB
40.21 kB
33.8 kB
34.68 kB
33.34 kB
35.3 kB
33.92 kB
35.7 kB
34.36 kB
35.99 kB
34.7 kB
34.85 kB
File End

File Start
11.32 MB
14.7 MB
15.98 MB
17.82 MB
18.02 MB
18.88 MB
18.93 MB
19.44 MB
40.76 kB
36.53 kB
40.17 kB
36.99 kB
40.07 kB
37.27 kB
39.92 kB
37.44 kB
39.77 kB
36.49 kB
34.81 kB
36.63 kB
35.15 kB
36.82 kB
35.51 kB
37.04 kB
35.71 kB
37.13 kB
34.66 kB
33.6 kB
34.8 kB
33.96 kB
35.09 kB
34.1 kB
35.17 kB
34.34 kB
35.35 kB
34.28 kB
File End

您会注意到我的问题是,我所说的“爆发”从每个新文件的开头开始,在 MB 中达到峰值,然后适当地平衡。像这样突然上传是正常的吗?我的上传速度在这里通常不会超过 40k/秒,所以它不可能是正确的。

这是一个真正的问题,当我将最后 5 到 10 秒的平均时间用于屏幕显示时,它确实会产生大约 3MB/秒左右的结果!

如果我以最好的方式解决这个问题,有什么想法吗?我应该怎么做? :S

格雷厄姆

另外:为什么我不能执行 'bytesPerSecond = (bytesRead / duration.Elapsed.TotalSeconds)' 并将 duration.Start 和 duration.Stop 移动到 while 循环中并获得准确的结果?我会认为这会更准确?每种速度读取为 900 字节/秒、800 字节/秒等。

【问题讨论】:

    标签: c# .net networking stream


    【解决方案1】:

    我这样做的方法是: 保存在 long 中传输的所有字节。

    然后我每隔 1 秒检查一次转移了多少。所以我基本上只触发一次代码来节省速度。您的 while 循环将在一秒钟内在快速网络上循环 maaaaaaaaaaaaany 次。

    根据您的网络速度,您可能需要检查在单独的线程或函数中传输的字节。我更喜欢用定时器来做这件事,这样我就可以轻松更新 UI

    编辑: 从你看你的代码,我猜你做错了什么是你没有考虑到 while(true) 中的一个循环不是 1 秒

    编辑2: 每秒只进行一次速度检查的另一个优点是事情会变得更快。在这种情况下,更新 UI 可能是您正在做的最慢的事情,所以如果您尝试在每个循环中更新 UI,那很可能是您最慢的一点,并且会产生无响应的 UI。

    你也正确,你应该平均出这些值,所以你不会得到microsoft minutes 错误。我通常通过执行以下操作在运行的 Timer 函数中执行此操作:

    //Global variables
    long gTotalDownloadedBytes;
    long gCurrentDownloaded; // Where you add up from the download/upload untill the speedcheck is done.
    int gTotalDownloadSpeedChecks;
    
    
    //Inside function that does speedcheck    
    gTotalDownloadedBytes += gCurrentDownloaded;
    gTotalDownloadSpeedChecks++;
    
    long AvgDwnSpeed = gTotalDownloadedBytes / gTotalDownloadSpeedChecks; // Assumes 1 speedcheck pr second.
    

    【讨论】:

    • 感谢您的评论,循环确实每 1024 块运行一次很快,但这也是为了顺利更新进度条,这一切正常,没有问题。我想我已经通过调整我的平均等待一秒钟来解决我的问题,但仍然不确定它为什么会这样爆发。
    • 感谢EKS,你对我的帮助最大,我看看我以后能不能优化。
    【解决方案2】:

    在您和您要发送到的系统之间有很多软件和硬件层,其中一些层有一定数量的可用缓冲区空间。

    当您第一次开始发送时,您可以很快地抽出数据,直到填满这些缓冲区 - 但实际上并没有那么快地到达另一端!填满发送缓冲区后,您只能以与耗尽相同的速率将更多数据放入其中,因此您看到的速率将下降到底层网络发送速率。

    【讨论】:

      【解决方案3】:

      所有,我想我已经解决了我的问题,方法是调整 5 - 10 平均变量以等待一秒钟来解决突发问题,而不是最好的,但可以让互联网自行解决并让我捕捉到流畅的传输.

      从我的网络流量看来,它向右下方正在爆发,因此我无法在代码中采取不同的措施来阻止这种情况。

      在我犹豫地接受我自己的答案之前,请仍然对更多答案感兴趣。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-16
        • 2011-06-27
        • 1970-01-01
        • 2011-03-09
        • 2021-02-01
        • 1970-01-01
        • 2012-12-12
        相关资源
        最近更新 更多