代码之家  ›  专栏  ›  技术社区  ›  GONeale

计算上传传输速度问题

  •  4
  • GONeale  · 技术社区  · 15 年前

    我已经实现了一个文件传输速率计算器来显示在我的应用程序中发生的一个上传过程的kb/s,但是通过下面的代码,在文件开始上传后,我的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) '和移动持续时间。开始持续时间。停止到while循环中并接收准确的结果?我本以为这会更准确?每种速度的读取速度为900字节/秒、800字节/秒等。

    3 回复  |  直到 15 年前
        1
  •  3
  •   EKS    15 年前

    我这样做的方式是: 保存长时间传输的所有字节。

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

    根据网络的速度,您可能需要检查在单独线程或函数中传输的字节。我更喜欢使用计时器进行此操作,以便轻松更新用户界面

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

    编辑2: 另一个只做一次速度检查公关秒的宣传是,事情会更快。在这种情况下,更新UI可能是您正在做的最慢的事情,因此如果您尝试在每个循环中更新UI,这很可能是您最慢的一点,并且将产生无响应的UI。

    你也正确的认为你应该利用价值观,所以你不会得到 microsoft minutes 漏洞。我通常在运行的计时器函数中这样做,方法如下:

    //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.
    
        2
  •  2
  •   caf    15 年前

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

    当您第一次开始发送数据时,您可以很快地抽取数据,直到填满这些缓冲区——但实际上并没有这么快地到达另一端!在填满发送缓冲区后,将限制以相同的速率向缓冲区中放入更多的数据,这样,您看到的速率将下降到底层网络发送速率。

        3
  •  0
  •   GONeale    15 年前

    总之,我认为我已经通过调整5-10平均值变量来解决了我的问题,让它等待一秒钟来解释突发事件,这不是最好的,但它将允许互联网自行解决,并允许我捕获一个平滑的传输。

    从我的网络流量来看,它右下角正在爆裂,所以代码中没有任何我可以做不同的事情来阻止它。

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