Рассчитать скорость в секунду и время, оставшееся до отправки файла с использованием сокетов tcp С#

Как я могу рассчитать скорость в секунду и оставшееся время в секундах? Я пытался использовать:

void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) {
    long prevSum = 0;
    while (fileTransfer.busy) {
        rate = (fileTransfer.sum - prevSum);
        RateLabel(rate);  //converting prevSum to (int)KB/SEC
        if (rate != 0)
            left = (fileTransfer.fileSize - fileTransfer.sum) / rate;
        TimeSpan t = TimeSpan.FromSeconds(left);
        timeLeftLabel(FormatRemainingText(rate, t)); //show how much left
        prevSum = fileTransfer.sum;
        Thread.Sleep(1000);
    }
}

но скорость и оставшееся время постоянно увеличиваются и уменьшаются (30 МБ / с, затем 5 МБ / с).

Это код файла отправки:

public static void sendFile(string filePath) {
    // run the progres Form
    Thread thFP = new Thread(fpRUN);
    fileProgress fP = new fileProgress("Sending...");
    thFP.Start(fP);

    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    string fileName = Path.GetFileName(filePath);
    byte[] fileData;
    try {
        //sending file name and file size to the server
        busy = true;
        fileSize = fs.Length;
        byte[] fileDetial = null;
        string detail =  fileName + "," + fileSize.ToString();
        fileDetial = Encoding.ASCII.GetBytes(detail);
        client.Send(fileDetial);

        //sending file data to the server
        fileData = new byte[packetSize];
        count = 0;
        sum = 0;                          

        fP.SizeLabel(fileSize); // tell the form the file size
        while (sum < fileSize) {
            fs.Seek(sum, SeekOrigin.Begin);
            fs.Read(fileData, 0, fileData.Length);
            count = client.Send(fileData, 0, fileData.Length, SocketFlags.None);
            sum += count;
            fP.ProgressBarFileHandler(sum,fileSize); //progressbar value
            fP.SentLabel(sum);                  //tell the form how much sent
        }
    }
    finally {
        busy = false;
        fs.Close();
        fileData = null;
        MessageBox.Show(string.Format("{0} sent successfully", fileName));
    }
}

Как я могу это исправить? Есть ли лучший способ рассчитать скорость?


person Murhaf Sousli    schedule 27.01.2012    source источник


Ответы (3)


Вы можете немного сгладить скорость передачи, чтобы избежать скачков значения. См. http://en.wikipedia.org/wiki/Moving_average для одного варианта. По сути, вычислите какое-то среднее значение скорости с течением времени.

person Alexei Levenkov    schedule 27.01.2012
comment
я не понял, что в вашей ссылке .. там было много математики .. но я думаю, я понял вашу точку зрения .. я думал об этом в первую очередь .. вы имеете в виду, когда значение увеличивается, например, более 2 МБ. .. я увеличиваю его на 0,5 МБ .. и если он падает, я делаю то же самое .. Это была твоя идея? - person Murhaf Sousli; 27.01.2012
comment
Что-то вроде этого. Простой подход тоже может работать нормально - вместо измерения последней скорости просто разделите переданные байты на затраченное время. Если вы хотите, чтобы значение менялось быстрее - нужно усреднять за меньший период времени. Вам нужно поэкспериментировать, чтобы получить хорошо выглядящие результаты, поскольку вы видите, что 1 секунда дает некрасивый результат. - person Alexei Levenkov; 27.01.2012
comment
Я думаю о том, чтобы брать отправленные байты три раза. Каждый раз, когда thread.sleep(1000/3) и после трех раз (что составляет секунду), я печатаю среднее из трех значений diff. Это поможет избежать моей проблемы? - person Murhaf Sousli; 27.01.2012
comment
я обновил свой код, можете ли вы проверить этот вопрос для меня times-of-getting-s" title="рассчитать скорость отправки файла в секундах, взяв среднее значение 10 раз получения s"> stackoverflow.com/questions/9030297/ - person Murhaf Sousli; 27.01.2012

Вы не можете это исправить. Единственный способ «исправить» это - создать сеть/интернет с постоянной скоростью.

сеть (и ваш компьютер) не имеет постоянной скорости.

Расчет говорит вам, что это такое.

person Emond Erno    schedule 27.01.2012
comment
Я хочу получить скорость в секунду .. так как я могу получить ее таким образом, о котором вы говорите? - person Murhaf Sousli; 27.01.2012
comment
Вы можете сгладить это, измерив количество байтов, переданных за более длительный период, скажем, за последние 20 секунд, и сдвиньте этот период. что сделает его более гладким. - person Emond Erno; 27.01.2012
comment
20 секунд!!! .. я должен начать печатать скорость в секунду, когда начнется отправка файла и до ее завершения. это то, что они делают во всех программах для передачи файлов !! - person Murhaf Sousli; 27.01.2012
comment
тогда сделайте это секунду. это зависит от вас. - person Emond Erno; 27.01.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");
        }
    }
person Murhaf Sousli    schedule 05.03.2012