c# - 计算上传传输速度问题

标签 c# .net networking stream

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

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

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/sec,所以这不太对。

这是一个真正的问题,当我对屏幕显示的最后 5 到 10 秒取平均值时,它确实会产生约 3MB/秒的结果!

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

格雷厄姆

另外:为什么我不能执行“bytesPerSecond = (bytesRead/duration.Elapsed.TotalSeconds)”并移动 duration.Start & duration.Stop 进入 while 循环并接收准确结果?我会认为这会更准确?每种读取速度为 900 字节/秒、800 字节/秒等。

最佳答案

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

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

根据您的网络速度,您可能需要检查在单独的线程或函数中传输的字节。我更喜欢使用计时器来执行此操作,这样我可以轻松更新 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.

关于c# - 计算上传传输速度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1700435/

相关文章:

c - socket() 中的类型和协议(protocol)有什么区别?

c# - 使用C#登录网站连接现有的sql server db

c# - 组合框的 SelectedValue 返回意外值

c# - 业务对象(在层次结构中)之间的循环引用是否常见?

java - TCP 客户端消息累积

android - 当互联网连接失败时,然后显示文本并重复循环直到连接可用?

c# - WebRequest 将 URL 转换为 Xamarin 中的编码 (MonoTouch)

c# - 在 Store C# 中按哈希查找证书

c# - 汉诺塔 : Moving Rings from Peg to Peg

c# - 系统.Data.Linq.ChangeConflictException : Row not found or changed