2012-11-28 17 views
9

C# .NET kullanarak Ağ Arayüzü üzerinden doğru indirme/yükleme hızı elde etmek istiyorum Bunun GetIPv4Statistics().BytesReceived kullanarak hesaplanabileceğini ve iş parçacığının bir süre uyumaya başladığını biliyorum. Ancak, tarayıcımda aldığım çıktıyı vermiyor.C# .NET'te doğru indirme/yükleme hızı nasıl edinilir?

+0

Ne kadar bir fark var? Başka hangi ağ trafiği var? –

+0

Uygulamamda sabit bir hız görmüyorum, tarayıcım sabit hız gibi bir şey gösteriyor. Uygulamam çok dalgalanıyor. –

+0

Verim nasıl hesaplanır? Çok fazla dalgalanma olmasını beklerdim. Bunu yapmak, hareketli ortalamanın yanlış hesaplandığını gösterebilir. –

cevap

4

NetworkInterface.GetIPv4Statistics().BytesReceived - What does it return?'da gönderdiğiniz bir soruyu başka bir yanıta bakarak, sorunun küçük aralıklarla kullandığınıza inanıyorum. Sayacın yalnızca tüm paketleri sayar olduğuna inanıyorum ve örneğin bir dosya indiriyorsanız, paketler 64 KB (65,535 bytes, IPv4 max paket boyutu) kadar büyük olabilir, bu da maksimum indirme çıktısı 60 KB/s ise ve çok fazla 200 ms aralıkları.

Hızınızın 60 KB/s olduğu göz önüne alındığında, ortalama olarak en az 9 paket almak için çalışma süresini 10 saniyeye ayarlayacağım. Her türlü bağlantı için yazıyorsanız, çözümü dinamik hale getirmenizi tavsiye ederim, yani hız yüksekse, ortalama aralığını kolayca azaltabilirsiniz, ancak yavaş bağlantı durumunda, ortalama aralığını arttırmalısınız.

@pst, hareketli bir ortalamaya sahip olmanızı önerir ya da sadece 1 saniyeye kadar uyku süresini artırır.

Ve Thread.Sleep()'a geçen zaman yerine alınan gerçek süreye göre bölünmüş olduğunuzdan emin olun. aralıklarla

My süreç

ek düşünce 5 saniye ölçmek ve veri toplamak, yani bayt alınan yanı sıra paket sayısı, böyle bir şey olurdu.

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

Bu, aralığın paketin başına kadar birkaç ms'den yavaşça yavaşça artmasına neden olur. Böylelikle her seferinde aralık başına en az bir paket alırız ve eğer 10 Gbps'lik bir bağlantıda olursak kaçak yapmayacağız. Önemli olan, ölçüm süresinin alınan veri miktarına doğrusal olmamasıdır.

+0

Teşekkürler. Aralığı arttırırsam, çıktıyı neredeyse doğru veriyor. Ama diğer NetworkInterfaces’lerin hızını da hesaplamalıyım. Dolayısıyla, belirli bir ağ arayüzünün hız değerini güncellemek için çok yavaş olacaktır. Öyleyse, @ pst'nin uygulanması için gitmem gerektiğini düşünüyorum. Ne düşünüyorsun? –

+1

@ soham.m17 Bunu da tavsiye ederim. Ve benim son düzenlemeye bak, daha hızlı bağlantı, daha küçük "zaman miktarı", çıktı ve maksimum IPv4 paket boyutu arasındaki oran nedeniyle gereklidir. Her zaman en az bir paketin üzerinde ortalama emin olun :) – flindeberg

+0

IP paketlerinin> 15xx bayt kullanılması olası değildir. Birkaç internet bağlantısı daha büyük bir MTU'yu desteklemektedir. – CodesInChaos

3

İşte LINQPad'den hızlı bir kod snippet'i. Çok basit bir hareketli ortalama kullanır. "Speedtest.net" kullanarak "doğru hızlar" gösterir. Akılda tutulması gerekenler şunlardır: Kbps bit ve HTTP verisi sık sık sıkıştırılır, böylece "indirilen baytlar" yüksek sıkıştırılabilir veriler için önemli ölçüde daha küçük olacaktır. Ayrıca, bu günlerde herhangi bir eski işlemin internette eski bir şey yaptığını da unutmayın (daha sıkı güvenlik duvarı ayarları olmadan).

Flindenberg'in cevabını seviyorum (kabul etmeyin) ve farkettim ki Bazı oylama periyotları, sonuçlarıyla uyumlu olan "0" ı döndürür.

Kendi tehlikenizde kullanın.

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

Teşekkürler. ama ben (i% 10 == 0) {// ~ 1 saniye 'kısmı varsa anlamıyorum. Çıkışı her 1 saniyede gösteriyorsunuz. öyle mi? –

+0

@ soham.m17 Evet. Bir saniyenin 1/10'undan daha kolay okunur. Alternatif olarak, sadece bir kez anket ve SMA N (4 belki?) Saniye demek için ayarlayın. –

+0

SMA ile ne demek istiyorsun? –

5

Lütfen bunu deneyin. İnternet bağlantı hızını kontrol etmek için.

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/Sec hızını verir ve sonucu paylaşır.

+0

Bunu deneyebilirsiniz. https://www.nuget.org/packages/InetSpeedWinRT/ –