calculer la vitesse d'envoi du fichier/s en moins d'une seconde (sans utiliser thread.sleep)

StackOverflow https://stackoverflow.com/questions/8987180

Question

Il s'agit d'un transfert de fichiers (sockets TCP Serveur-Client)

Le code ci-dessous indique le taux de transfert par seconde (kb/s) toutes les secondes.

Je veux montrer la vitesse (rate/s) chaque fois que j'envoie les données au client.Comment calculer la vitesse à chaque fois (sans utiliser 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);
        }
    }
Était-ce utile?

La solution 2

dans le constructeur de formulaire

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

ou ajoutez-le depuis la boîte à outils et définissez les valeurs précédentes

la somme des octets envoyés doit être publique afin que notre méthode puisse obtenir sa valeur chaque seconde

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

Autres conseils

Vous avez deux décisions à prendre :

  1. Sur combien de temps souhaitez-vous prendre la vitesse moyenne de transfert ?
  2. À quelle fréquence souhaitez-vous mettre à jour/rapporter le résultat ?

Rappelons qu’il n’existe pas de vitesse de transfert instantanée actuelle.Ou, plus exactement, la vitesse de transfert instantanée actuelle est toujours soit la vitesse physique totale de votre interface réseau (par ex.100 Mbps) ou zéro, correspondant aux situations « il y a un paquet envoyé/reçu à cette microseconde » et « la ligne est inactive ».Il faut donc faire la moyenne.

Dans le code ci-dessus, vous avez choisi une seconde comme valeur pour (1) et (2).(1) et (2) étant égaux est le cas le plus simple à coder.

Je vous recommande de choisir une période plus longue pour (1).Une moyenne sur seulement une seconde entraînera une vitesse de transfert assez instable sur tous les transferts de fichiers, sauf les plus fluides.Considérez, par exemple, que Cisco IOS dure en moyenne plus de 5 minutes par défaut et ne vous permet pas de configurer moins de 30 secondes.

Pour (2), vous pouvez continuer à utiliser 1 seconde, ou, si vous le souhaitez, même moins d'une seconde.

Choisissez une valeur pour (1) qui est un multiple de la valeur que vous choisissez pour (2).Laisser n être (1) divisé par (2).Par exemple, (1) correspond à 10 secondes, (2) correspond à 500 ms et n=20.

Créez un tampon en anneau avec n entrées.Chaque fois que (2) s'écoule, remplacez l'entrée la plus ancienne dans le tampon en anneau par le nombre d'octets transférés depuis le temps précédent (2), puis recalculez la vitesse de transfert comme la somme de toutes les entrées dans le tampon divisée par (1). .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top