Как получить точную скорость загрузки / выгрузки в C#.NET?

Я хочу получить точную скорость загрузки/выгрузки через сетевой интерфейс с помощью C# .NET Я знаю, что его можно вычислить с помощью GetIPv4Statistics().BytesReceived и положить нить, чтобы спать на некоторое время. Но это не дает вывода, что я получаю в своем браузере.

3 ответов


посмотрев на другой ответ на вопрос, который вы разместили в NetworkInterface.GetIPv4Statistics ().BytesReceived-что он возвращает? Я считаю, что проблема может быть в том, что вы используете для небольших интервалов. Я считаю, что счетчик подсчитывает только целые пакеты, и если вы, например, загружаете файл, пакеты могут быть размером 64 KB (65,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. Важная часть заключается в том, что время измерения не должно быть линейным по отношению к объему полученных данных.


вот быстрый фрагмент кода из LINQPad. Он использует очень простую скользящую среднюю. Он показывает "точные скорости", используя "Speedtest.net". Вещи, которые нужно иметь в виду, - это Kbps в bits и HTTP-данные часто сжимаются, поэтому "загруженные байты" будут значительно меньше для сильно сжимаемых данных. Кроме того, не забывайте, что любой старый процесс может делать любую старую вещь в интернете в эти дни (без более строгих настроек брандмауэра) ..

Мне нравится flindenberg по ответ (не меняйте accept), и я заметил, что некоторые периоды опроса вернут "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);
        }
    }
}

пожалуйста, попробуйте это. Чтобы проверить скорость подключения к интернету.

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

Это дает вам скорость в Кб/сек и поделиться результатом.