2012-11-28 43 views
9

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

+0

它有多大的区别?还有什么其他网络流量? – 2012-11-28 08:19:32

+0

我在应用程序中看不到恒定的速度,而我的浏览器显示恒定速度。我的应用程序非常波动。 –

+0

吞吐量是如何计算的?我预计它不会波动很多。这样做可能表明移动平均线计算错误。 – 2012-11-28 08:24:59

回答

4

通过查看您在NetworkInterface.GetIPv4Statistics().BytesReceived - What does it return?中发布的问题的另一个答案,我认为问题可能是您正在使用较小的间隔。我认为该计数器只计算整个软件包,如果您例如正在下载文件,软件包可能会大到64 KB65,535 bytes,IPv4最大软件包大小),如果您的最大下载吞吐量为60 KB/s并且您正在测量200 ms区间。

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

要么@pst建议通过移动平均值或简单地将睡眠时间增加到1秒。

而且一定要除以实际所用的时间,而不是时间流逝到Thread.Sleep()

打开间隔

我的过程中附加想到会是这样的,测量5秒钟,并收集数据,即字节收到以及数据包的数量。

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

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

+0

谢谢。如果我增加间隔,它会使输出几乎正确。但是我也必须计算其他NetworkInterfaces的速度。因此,更新一个特定网络接口的速度值将会太慢。所以,我认为我应该去@ pst的实施。你怎么看? –

+1

@ soham.m17我也建议。并且看到我的上一次编辑,由于吞吐量和最大IPv4封装大小之间的比率,更短的“时间量”是必要的。总是要确保平均至少有几个包:) – flindeberg

+0

似乎不太可能使用ip包> 15xx字节。很少有互联网连接支持更大的MTU。 – CodesInChaos

3

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

我喜欢flindenberg的回答(不要改变接受),我注意到一些投票时间段将返回与他/她的结论一致的“0”。

用于你自己的危险。

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); 
     } 
    } 
} 
+0

谢谢。但我没有得到'if(i%10 == 0){//〜1秒'部分。你每1秒显示一次输出。是这样吗? –

+0

@ soham.m17是的。阅读比每秒十分之一更容易阅读。或者,只需每秒调查一次,然后将SMA调整为N(4可能?)秒。 – 2012-11-28 09:16:00

+0

SMA是什么意思? –

5

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

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);    
    } 

它给你以Kb /秒的速度并分享结果。

+0

你可以试试这个。 https://www.nuget.org/packages/InetSpeedWinRT/ –