web-dev-qa-db-ja.com

C#.NETで正確なダウンロード/アップロード速度を取得するにはどうすればよいですか?

C#.NETを使用してネットワークインターフェイスを介して正確なダウンロード/アップロード速度を取得したい。GetIPv4Statistics().BytesReceivedを使用して計算でき、スレッドをしばらくスリープ状態にすることができることを知っています。しかし、それは私が私のブラウザで得ているものを出力に与えていません。

10
soham

あなたが投稿した質問に対する別の答えを見ると NetworkInterface.GetIPv4Statistics()。BytesReceived-何が返されますか? 問題はあなたが小さな間隔で使用していることかもしれないと思います。カウンターはパッケージ全体のみをカウントすると思います。たとえば、ファイルをダウンロードしている場合、パッケージは_64 KB_(_65,535 bytes_、IPv4の最大パッケージサイズ)と同じくらい大きくなる可能性があります。ダウンロードスループットは_60 KB/s_であり、_200 ms_間隔を測定しています。

あなたの速度が_60 KB/s_であるとすると、平均で少なくとも9つのパッケージを取得するには、実行時間を10秒に設定します。すべての種類の接続に対して作成する場合は、ソリューションを動的にすることをお勧めします。つまり、速度が速い場合は平均化間隔を簡単に短くできますが、接続が遅い場合は平均化間隔を長くする必要があります。

@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);
_

これにより、間隔は約数十ミリ秒からパケットあたりの時間までゆっくりと増加します。そうすれば、間隔ごとに常に少なくとも(平均して)1つのパッケージを取得でき、10Gbps接続を使用している場合は問題が発生しません。重要な部分は、測定時間が受信したデータの量に対して線形であってはならないということです。

4
flindeberg

これは、LINQPadのコードの簡単な抜粋です。非常に単純な移​​動平均を使用します。 「Speedtest.net」を使用して「正確な速度」を表示します。覚えておくべきことはKbps is in bitsであり、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);
        }
    }
}
8
user166390

ぜひお試しください。インターネット接続速度を確認します。

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

それはあなたにキロバイト/秒で速度を与えて、結果を共有します。

6
Sandeep Gupta