рассчитать скорость отправки файла / сек менее чем за секунду (без использования thread.sleep) - PullRequest
0 голосов
/ 24 января 2012

Это передача файла (tcp сокеты сервер-клиент)

Приведенный ниже код показывает скорость передачи в секунду (кбит / с) каждую секунду.

Я хочу показатьскорость (rate/s) каждый раз, когда я отправляю данные клиенту.Как рассчитать скорость каждый раз (без использования thread.sleep(1000))?

private void timeElasped()
    {
        int rate = 0;
        int prevSent = 0;
        while (fileTransfer.busy)
        {
            rate = fileTransfer.Sent - prevSent ;
            prevSum = fileTransfer.Sent;
            RateLabel(string.Format("{0}/Sec", CnvrtUnit(rate)));
            if(rate!=0)
                Timeleft = (fileTransfer.fileSize - fileTransfer.sum) / rate;
            TimeSpan t = TimeSpan.FromSeconds(Timeleft);
            timeLeftLabel(FormatRemainingText(rate, t));
            Thread.Sleep(1000);
        }
    }

Ответы [ 2 ]

1 голос
/ 24 января 2012

Вам нужно принять два решения:

  1. Сколько времени вы хотите взять среднюю скорость передачи?
  2. Как часто вы хотите обновить / сообщить результат?

Напомним, что не существует такой вещи, как текущая мгновенная скорость передачи. Или, точнее, текущая мгновенная скорость передачи всегда равна либо полной физической скорости вашего сетевого интерфейса (например, 100 Мбит / с), либо нулю, в соответствии с ситуациями «есть пакет, отправляемый / получаемый в эту микросекунду» и «линия простаивает ". Так что вы должны в среднем.

В приведенном выше коде вы выбрали одну секунду в качестве значения для (1) и (2). (1) и (2) равенство является простейшим случаем для кода.

Я рекомендую вам выбрать более длительный период для (1). Усреднение всего за одну секунду обеспечит довольно резкую скорость передачи на всех передачах, кроме самых плавных. Например, учтите, что по умолчанию Cisco IOS занимает более 5 минут и не позволяет настраивать менее 30 секунд.

Для (2) вы можете продолжать использовать 1 секунду или, если хотите, даже менее одной секунды.

Выберите значение для (1), кратное значению, выбранному вами для (2). Пусть n будет (1) делится на (2). Например, (1) составляет 10 секунд, (2) составляет 500 мс и n=20.

Создать кольцевой буфер с n записями. Каждый раз по истечении (2) замените самую старую запись в кольцевом буфере количеством байтов, переданных с момента истечения предыдущего времени (2), а затем пересчитайте скорость передачи в виде суммы всех записей в буфере, деленной на (1) .

0 голосов
/ 06 марта 2012

в конструкторе форм

Timer timer1 = new Time();
public Form1()
{
    InitializeComponent();
    this.timer1.Enabled = true;
    this.timer1.Interval = 1000;
    this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}

или добавьте его из панели инструментов и установите предыдущие значения

сумма отправленных байтов должна быть публичной, чтобы наш метод мог получать ее значение каждую секунду

long sentBytes = 0;      //the sent bytes that updated from sending method
long prevSentBytes = 0;   //which references to the previous sentByte
double totalSeconds = 0;   //seconds counter to show total time .. it increases everytime the timer1 ticks.
private void timer1_Tick(object sender, EventArgs e)
{
    long speed = sentBytes - prevSentBytes ;  //here's the Transfer-Rate or Speed
    prevSentBytes = sentBytes ;
    labelSpeed.Text = CnvrtUnit(speed) + "/S";   //display the speed like (100 kb/s) to a label
    if (speed > 0)                //considering that the speed would be 0 sometimes.. we avoid dividing on 0 exception
    {
        totalSeconds++;     //increasing total-time
        labelTime.Text = TimeToText(TimeSpan.FromSeconds((sizeAll - sumAll) / speed));
        //displaying time-left in label
        labelTotalTime.Text = TimeToText(TimeSpan.FromSeconds(totalSeconds));
        //displaying total-time in label
    }
}

private string TimeToText(TimeSpan t)
{
    return string.Format("{2:D2}:{1:D2}:{0:D2}", t.Seconds, t.Minutes, t.Hours);
}

private string CnvrtUnit(long source)
{
    const int byteConversion = 1024;
    double bytes = Convert.ToDouble(source);

    if (bytes >= Math.Pow(byteConversion, 3)) //GB Range
    {
        return string.Concat(Math.Round(bytes / Math.Pow(byteConversion, 3), 2), " GB");
    }
    else if (bytes >= Math.Pow(byteConversion, 2)) //MB Range
    {
        return string.Concat(Math.Round(bytes / Math.Pow(byteConversion, 2), 2), " MB");
    }
    else if (bytes >= byteConversion) //KB Range
    {
        return string.Concat(Math.Round(bytes / byteConversion, 2), " KB");
    }
    else //Bytes
    {
        return string.Concat(bytes, " Bytes");
    }
}
...