Seite 1 von 1

Downloader programmieren

Verfasst: 22. April 2010 18:12
von marvel
hallo,
ich sitze gerade an einem größeren projekt und komme an einem punkt nicht weiter. ich möchte es dem anwender meiner software ermöglichen dateien von einem server zu laden. dazu müssen bestimmte werte angegeben werden die dann als http request an einen server gesendet werden und der dann eine datei an den client zurückschickt. die übertragung klappt soweit ganz gut, nur komme ich mit den übertragngsdetails nicht ganz zurecht (wieviele bytes/s, wieviel zeit vergangen ist, wieviele bytes insgesamt übertragen wurden). ich arbeite mit dem framework qt. es gibt eine klasse qtime die es ermöglicht eine art stoppuhr zu benutzen. ich starte die uhr und frage nach wieviele sekunden nach dem letzten start vergangen sind. sind mehr als oder genau 1000 ms vergangen, also 1 sekunde, sollen alle statusdetails aktualisiert werden (Downloadspeed/s, Received Bytes, Elapsed Time).

Code: Alles auswählen

// Zustand der Downloadrate, der Downloadzeit und des Downloadvolumens aktualisieren
void Downloader::updateDataReadProgress(int bytesRead, int totalBytes)
{
    if(time->isNull())
    {
        qDebug() << "Timer gestartet";
        time->start();
    }
    
    // Aktualisierung pro Sekunde durchführen
    if(time->elapsed() >= 1000)
    {                
        int dSpeed = bytesRead - bytesTemp;
        bytesTemp = bytesRead;

        if(dSpeed >= 1000000)
        {
            dSpeed = dSpeed / 1000000;
            gui_downloader->getLabelSpeed()->setText(QString::number(dSpeed) + " MByte/s");
        }
        else if(dSpeed >= 1000)
        {
            dSpeed = dSpeed / 1000;
            gui_downloader->getLabelSpeed()->setText(QString::number(dSpeed) + " kByte/s");
        }
        else
        {
            gui_downloader->getLabelSpeed()->setText(QString::number(dSpeed) + " Byte/s");
        }
        
        //Verstrichene Zeit
        gui_downloader->getLabelTime()->setText(QString::number(test));

        if(bytesRead >= 1000000)
        {
            bytesRead = bytesRead / 1000000;
            gui_downloader->getLabelSize()->setText(QString::number(bytesRead) + " MByte");
        }
        else if(bytesRead >= 1000)
        {
            bytesRead  = bytesRead / 1000;
            gui_downloader->getLabelSize()->setText(QString::number(bytesRead) + " kByte");
        }
        else
        {
            gui_downloader->getLabelSize()->setText(QString::number(bytesRead) + " Byte");
        }    
        
        //Zeit zurücksetzen
        qDebug() << "Timer zurückgesetzt";
        time->restart();
    }
}
die funktion wird mehrmals in der sekunde aufgerufen. bytesread enthält die bisher übertragenen bytes. um an den downloadspeed pro sekunde zu kommen habe ich einfach

Code: Alles auswählen

 int dSpeed = bytesRead - bytesTemp;
        bytesTemp = bytesRead;
genommen.

das problem was ich jetzt habe ist das es nicht genau pro sekunde ist. habe eine stoppuhr daneben laufen lassen. das kommt daher das die if abfrage nicht genau bei 1000ms greift sondern der wert immer ein paar ms drüber liegt. gubt es eine andere möglichkeit solch einen downloader zu implementieren oder hat einer einen tip für mich ?

lg

marvel

Verfasst: 22. April 2010 18:28
von Christian81
Und wo liegt jetzt das Problem?

Verfasst: 22. April 2010 18:32
von RavenIV
Warum benutzt Du nicht einen QTimer.
Der ist relativ genau.

In der Timer-Funktion (onTimer) wertest Du die vergangene Zeit seit Downloadstart aus. Mit der Anzahl runtergeladenen Bytes kannst Du die Byte/Sec berechnen.

Einfach aber effektiv.

Verfasst: 22. April 2010 18:35
von Exasperation
Als elegantere Lösung: QTimer anstatt der if-Abfrage.. auf eine genauere Anzahl an ms kommst du dadurch allerdings auch nicht. Sonst ist doch alles in Ordnung... Die if-Abfrage greift nunmal erst sobald 1000 erreicht oder überschritten sind, erst in den folgenden ns oder ms wird dann der Rumpf abgearbeitet, erst danach geht die if-Abfrage von neuem los...
Wenn es dich stört, dass du auf deiner Stoppuhr dann 1,05 Sekunden abliest stell die if-Abfrage (oder den QTimer) doch einfach auf 950ms ;)


/edit... naja zu langsam :roll:

Verfasst: 22. April 2010 18:38
von RavenIV
Übrigens hast Du noch einen Fehler bei der Umrechnung im MB und kB.

1 kB = 1024 Bytes
1 MB = 1024 kB
1MB = 1048576 Bytes (1024 x 1024 Bytes)

Verfasst: 16. Mai 2010 20:14
von marvel
danke für alle antworten, habe das problem jetzt gelöst. kann geschlossen werden !