Qt Klasse modifizieren



  • Hallo!

    Ich habe schon 2 Andere Topics aufgemacht, die auch Probleme behandeln, die ich dabei hatte, der QT-Klasse QTcpSocket eine Drosselfunktion hinzuzufügen, die die Verbindungsgeschwindigkeit herabsetzt.

    Ich weiß mittlerweile, wie ich das ganze realisieren will:
    Ich habe vor, die Funktion readData, die für das Auslesen der Daten aus dem QAbstractSocketEngine in den QAbstractSocket zuständig ist, dahingehend zu modifizieren, dass sie nur noch eine bestimmte Menge an Daten pro Zeiteinheit ausliest. Da QAbstractSocketEngine eine feste Puffergröße hat, kann ich somit verhindern, dass Daten mit maximaler Geschwindigkeit übertragen werden. Ich denke dass das die einfachste Möglichkeit ist, da ich mich mit den Socket-Innereien in der QAbstractSocketEngine nicht befassen muss, da diese Datei unverändert bleiben könnte.

    Ich kopiere Also die Dateien qabstractsocket.cpp, qabstractsocket_p.h sowie qabstractsocket.h aus den QT-Sources heraus in meine eigenes Projekt. Das Eigentiche Problem ist jetzt, dass ich ja die ganzen Include-Pfade verändern muss.

    Beispielsweise in der qabstractsocket.cpp

    #include "qabstractsocket.h"
    #include "qabstractsocket_p.h"
    
    #include <qabstracteventdispatcher.h>
    #include <qdatetime.h>
    #include <qhostaddress.h>
    #include <qhostinfo.h>
    #include <qmetaobject.h>
    #include <qpointer.h>
    #include <qtimer.h>
    
    #ifndef QT_NO_OPENSSL
    #include <QtNetwork/qsslsocket.h>
    #endif
    
    #include <private/qthread_p.h>
    
    #ifdef QABSTRACTSOCKET_DEBUG
    #include <qdebug.h>
    #endif
    
    #include <time.h>
    
    #define Q_CHECK_SOCKETENGINE(returnValue) do { \
        if (!d->socketEngine) { \
            return returnValue; \
        } } while (0)
    
    #define QABSTRACTSOCKET_BUFFERSIZE 32768
    #define QT_CONNECT_TIMEOUT 30000
    #define QT_TRANSFER_TIMEOUT 120000
    
    #if defined QABSTRACTSOCKET_DEBUG
    #include <qstring.h>
    #include <ctype.h>
    

    würde ich jetzt so ersetzen:

    #include "qabstractsocket.h"
    #include "qabstractsocket_p.h"
    
    #include <QAbstractEventDispatcher>
    #include <QDateTime>
    #include <QHostAddress>
    #include <QHostInfo>
    #include <QMetaObject>
    #include <QPointer>
    #include <QTimer>
    
    #ifndef QT_NO_OPENSSL
    #include <QSslSocket>
    #endif
    
    #include <private/qthread_p.h>
    
    #ifdef QABSTRACTSOCKET_DEBUG
    #include <qdebug.h>
    #endif
    
    #include <time.h>
    
    #define Q_CHECK_SOCKETENGINE(returnValue) do { \
        if (!d->socketEngine) { \
            return returnValue; \
        } } while (0)
    
    #define QABSTRACTSOCKET_BUFFERSIZE 32768
    #define QT_CONNECT_TIMEOUT 30000
    #define QT_TRANSFER_TIMEOUT 120000
    
    #if defined QABSTRACTSOCKET_DEBUG
    #include <QString>
    #include <ctype.h>
    

    Zeilen 1 und 2 bleiben logischerweise gleich.
    Zeilen 4-10 habe ich durch die entsprechenden Includes aus der QT-Dokumentation erstetzt, Auch bei QSSLSocket sollte das Funktionieren.
    In Zeile 12 und 18 habe ich allerdings schon ein Problem: Wo kriege ich die Werte dieser Konstanten her, wo wird das in dem Code eingebunden?

    Zeilen 22 und 35 passen auch, da Standardbibliothek.

    Die Frage ist wo ich Zeile 19 und Zeile 16 herkriegen soll.

    Ähnliche Probleme habe ich in der qabstractsocket_p.h
    Hier müsste ich folgendes einbinden:

    #include "private/qringbuffer_p.h"
    #include "private/qiodevice_p.h"
    #include "private/qnativesocketengine_p.h"
    

    Meine Überlegungen: Ich könnte natürlich die jeweiligen Dateien auch noch in mein Projekt kopieren. Das Problem ist, dass ich dann eben eine riesige Menge an Dateien einbinden müsste, da von den einzubindenden Files einige wiederrum ander e Files benötigen...

    Gibt es hierzu eine Alternative? Kann ich die Dateien einfach auch via #include <qringbuffer_p.h> einbinden?
    Prinzipielle Fragen: Woher weiß der Computer eigentlich bei dynamisch gelinkten Dateien, aus welcher Bibliothek er diese nehmen muss? Woher weiß er, dass #include <QAbstractSocket> ein Teil der QT-Library ist. Kann man irgendwo eine Liste der Klassen, die man so einbinden kann ausgeben?

    Danke,
    Tommm


  • Mod

    Könntest du nicht einfach von QTCPSocket ableiten, und dann die Methode überschreiben?
    readData ist schließlich virtuell: http://doc.trolltech.com/4.1/qiodevice.html#readData

    Es ist immer eine schlechte Idee, Code aus einer Library rauszulösen, da dieser i.d.R. eine Menge Abhängigkeiten mit sich bringt.



  • Das sollte denke ich nicht funktionieren.

    Da ich die Funktion QAbstractSocketPrivate::readFromSocket() verändern muss, Funktionen dieser Klasse kann ich in QTcpSocket als von QAbstractSocket abgeleitete Klasse nicht verändern.

    Liege ich falsch?



  • Also falls das grade nicht klar rausgekommen ist, ich will ja dort eingreifen, wo die Daten von dem SocketEngine in den readBuffer gelesen werden, denn der Readbuffer kann ja eine relativ große Größe annehmen, wohingegen der Puffer des SocketEngines auf 4048 Bytes beschränkt ist.


  • Mod

    Tommm schrieb:

    Also falls das grade nicht klar rausgekommen ist, ich will ja dort eingreifen, wo die Daten von dem SocketEngine in den readBuffer gelesen werden, denn der Readbuffer kann ja eine relativ große Größe annehmen, wohingegen der Puffer des SocketEngines auf 4048 Bytes beschränkt ist.

    Also ich kenn mich mit den Details der QT Socketimplementierung nicht aus, aber ich denke das es wohl am einfachsten ist, zu schauen ob es in den Klassen virtuelle Methoden gibt, die man überschreiben kann.
    Evtl. kannst du auch die Buffergröße irgendwo einstellen, diverse Setmethoden mit hat die Klasse ja:
    http://doc.trolltech.com/4.1/qabstractsocket.html#setReadBufferSize



  • wäre es nicht das einfachste, wenn du bei eigehenden daten das signal readyRead() einfach ignorierst und mittels eines timers alle x ms per hand mittels bytesAvaible nachschaust, ob welche da sind und dann mittels read(qint64 maxSize) nur so viele ausliest, wie es deine übertragungsrate erlaubt. (wobei du dir dsa bytesAvaible auch sparen kannst, wenn einen getimeten aufruf von read durchführst. sieht aber richtiger aus.) das sollte sobald der interne puffer voll ist, was sehr schnell geschehen wird, eine max übertragungsrate garantieren können.

    für den ausgang baust du dir eine klasse, die ein socket als member hat und über seinen eigenen buffer verfügt, der dann wieder mittels eines timer die daten in den socket schreibt.


Log in to reply