如何在 C#.NET 中获得准确的下载/上传速度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13600604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:08:33  来源:igfitidea点击:

How to get accurate download/upload speed in C#.NET?

c#.netnetwork-interface

提问by soham

I want to get accurate download/upload speed through a Network Interface using C# .NET I know that it can be calculated using GetIPv4Statistics().BytesReceivedand putting the Thread to sleep for sometime. But it's not giving the output what I am getting in my browser.

我想通过使用 C# .NET 的网络接口获得准确的下载/上传速度我知道它可以使用计算GetIPv4Statistics().BytesReceived并让线程休眠一段时间。但它没有给出我在浏览器中得到的输出。

采纳答案by flindeberg

By looking at another answer to a question you posted in NetworkInterface.GetIPv4Statistics().BytesReceived - What does it return?I believe the issue might be that you are using to small intervals. I believe the counter only counts whole packages, and if you for example are downloading a file the packages might get as big as 64 KB(65,535 bytes, IPv4 max package size) which is quite a lot if your maximum download throughput is 60 KB/sand you are measuring 200 msintervals.

通过查看您在NetworkInterface.GetIPv4Statistics().BytesReceived 中发布的问题的另一个答案- 它返回什么?我相信问题可能是你习惯了小间隔。我相信计数器只计算整个包,并且例如,如果您正在下载文件,则包可能会变得与64 KB( 65,535 bytes, IPv4 最大包大小)一样大,如果您的最大下载吞吐量为60 KB/s并且您正在测量200 ms间隔,则这相当多。

Given that your speed is 60 KB/sI would have set the running time to 10 seconds to get at least 9 packages per average. If you are writing it for all kinds of connections I would recommend you make the solution dynamic, ie if the speed is high you can easily decrease the averaging interval but in the case of slow connections you must increase the averaging interval.

考虑到您的速度,60 KB/s我会将运行时间设置为 10 秒,以平均获得至少 9 个包。如果您正在为各种连接编写它,我建议您使解决方案动态化,即如果速度很高,您可以轻松减少平均间隔,但在连接速度较慢的情况下,您必须增加平均间隔。

Either do as @pst recommends by having a moving average or simply increase the sleep up to maybe 1 second.

要么按照@pst 建议的方法使用移动平均线,要么简单地将睡眠时间延长至 1 秒。

And be sure to divide by the actual time taken rather than the time passed to Thread.Sleep().

并且一定要除以实际花费的时间而不是传递给 的时间Thread.Sleep()

Additional thought on intervals

关于间隔的额外思考

My process would be something like this, measure for 5 second and gather data, ie bytes recieved as well as the number of packets.

我的过程将是这样的,测量 5 秒并收集数据,即收到的字节数以及数据包的数量。

var timePerPacket = 5000 / nrOfPackets; // Time per package in ms
var intervalTime = Math.Max(d, Math.Pow(2,(Math.Log10(timePerPacket)))*100);

This will cause the interval to increase slowly from about several tens of ms up to the time per packet. That way we always get at least (on average) one package per interval and we will not go nuts if we are on a 10 Gbps connection. The important part is that the measuring time should not be linear to the amount of data received.

这将导致间隔从大约几十毫秒缓慢增加到每个数据包的时间。这样我们每个间隔总是至少(平均)得到一个包,如果我们使用 10 Gbps 连接,我们就不会发疯。重要的部分是测量时间不应与接收到的数据量成线性关系。

回答by flindeberg

Here is a quick snippet of code from LINQPad. It uses a very simple moving average. It shows "accurate speeds" using "Speedtest.net". Things to keep in mind are Kbps is in bitsand HTTP data is often compressed so the "downloaded bytes" will be significantly smaller for highly compressible data. Also, don't forget that any old process might be doing any old thing on the internet these days (without stricter firewall settings) ..

这是来自 LINQPad 的快速代码片段。它使用一个非常简单的移动平均线。它使用“Speedtest.net”显示“准确的速度”。要记住的事情是 Kbps 以单位,并且 HTTP 数据通常被压缩,因此对于高度可压缩的数据,“下载的字节”将显着更小。另外,不要忘记,如今任何旧进程都可能在互联网上做任何旧事(没有更严格的防火墙设置)..

I like flindenberg's answer (don't change the accept), and I noticed that some polling periods would return "0" that aligns with his/her conclusions.

我喜欢弗林登伯格的回答(不要改变接受),我注意到一些投票期会返回与他/她的结论一致的“0”。

Use at your own peril.

使用后果自负。

void Main()
{
    var nics = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    // Select desired NIC
    var nic = nics.Single(n => n.Name == "Local Area Connection");
    var reads = Enumerable.Empty<double>();
    var sw = new Stopwatch();
    var lastBr = nic.GetIPv4Statistics().BytesReceived;
    for (var i = 0; i < 1000; i++) {

        sw.Restart();
        Thread.Sleep(100);
        var elapsed = sw.Elapsed.TotalSeconds;
        var br = nic.GetIPv4Statistics().BytesReceived;

        var local = (br - lastBr) / elapsed;
        lastBr = br;

        // Keep last 20, ~2 seconds
        reads = new [] { local }.Concat(reads).Take(20);

        if (i % 10 == 0) { // ~1 second
            var bSec = reads.Sum() / reads.Count();
            var kbs = (bSec * 8) / 1024; 
            Console.WriteLine("Kb/s ~ " + kbs);
        }
    }
}

回答by Sandeep Gupta

Please try this. To check internet connection speed.

请试试这个。检查互联网连接速度。

 public double CheckInternetSpeed()
 {
        // Create Object Of WebClient
        System.Net.WebClient wc = new System.Net.WebClient();

        //DateTime Variable To Store Download Start Time.
        DateTime dt1 = DateTime.Now;

        //Number Of Bytes Downloaded Are Stored In ‘data'
        byte[] data = wc.DownloadData("http://google.com");

        //DateTime Variable To Store Download End Time.
        DateTime dt2 = DateTime.Now;

        //To Calculate Speed in Kb Divide Value Of data by 1024 And Then by End Time Subtract Start Time To Know Download Per Second.
        return Math.Round((data.Length / 1024) / (dt2 - dt1).TotalSeconds, 2);            
    }

It gives you the speed in Kb/Sec and share the result.

它为您提供 Kb/Sec 的速度并分享结果。