QTcpSocket in QThread



  • Hallo Leute

    ich arbeite aktuell an einem Socket der von einem QThread getrieben wird.
    D.h. wiederum, dass ich auf jegliche Signale verzichte und den Socket quasi in Eigenregie beschreibe und auslese.

    Das write/Versenden funktioniert bereits, aber derzeit scheint es so,
    dass der Sock->bytesAvailable() Aufruf niemals groesser als 0 wird und somit nie etwas gelesen wird. Ich weiß aber, dass die Gegenstelle Daten an mich versendet.

    die Run-Funktion sieht folgendermaßen aus:

    void ActiveConnection::run()
    {
        while ( State != csDisconnected )
        {
            switch( State )
            {
                case csInit :
                    Sock = new QTcpSocket();
                    Sock->blockSignals( true );
                    Sock->connectToHost( IP, Port );
                    if ( Sock->waitForConnected( 10000 ) )
                        State = csConnected;
                    break;
                case csConnected :
                    CheckConnection();
                    break;
                case csDisconnected :
                    break;
                case csFailed :
                    DisconnectConnection();
                    break;
            }
            ReadQueue();
        }
    }
    

    Und CheckConnection sieht folgendermaßen aus:

    void ActiveConnection::CheckConnection()
    {
        if ( Sock )
        {
            if ( Sock->bytesAvailable() > 0 )
            {
                qint64 LenDataRead = Sock->read( ReadBuffer + ActPosRead, ReadBufferSize - ActPosRead );
                if ( LenDataRead < 0 )
                    State = csFailed;
                else if ( LenDataRead > 0 )
                {
                    LogMessage( "IN", ReadBuffer + ActPosRead, (int)LenDataRead );
    
                    ActPosRead += (int)LenDataRead;
    
                    // Verarbeiten Daten
                    ActPosRead -= OnData( ReadBuffer, ActPosRead );
                }
            }
    
            // Versenden alles
            if ( ActPosWrite > 0 )
            {
                LogMessage( "OUT", WriteBuffer, ActPosWrite );
    
                qint64 LenDataSent = Sock->write( WriteBuffer, ActPosWrite );
                Sock->flush();
                if ( LenDataSent < 0 )
                    State = csFailed;
                else
                    ActPosWrite -= (int)LenDataSent;
            }
        }
    }
    

    1. Nun stellt sich mir die Frage, wieso nichts empfangen wird. Jemand eine Idee?
    Der Thhread läuft jedenfalls und ruft auch BytesAvailable auf.

    2. Gibt es generelle Kritik an meiner Vorgehensweise mit QTcpSocket und QThread? Ist das alles Bullshit, kann man das so machen, macht man es lieber anders?

    3. Zudem bekomme ich beim Beenden der Applikation einen Runtime-Error:

    ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 3e58f0. Receiver '' (of type 'QAbstractSocket') was created in thread 3ecd30", file kernel/qcoreapplication.cpp, line 469

    Daraus schließe ich, dass die Signale aus dem QTcpSocket noch nicht komplett verhindert wurden. Wo liegt die Ursache für den Fehler und was habe ich falsch gemacht?

    gruß

    Tobias



  • Ich schätz mal, du musst auf das readyRead Signal warten. Was aber nicht ankommen kann, weil du keine Event Loop hast. Also würd ich vielleicht sowas machen:

    QEventLoop loop;
    connect(Sock, SIGNAL(readyRead()), &loop, SLOT(quit()));
    loop.exec();
    if (Sock->bytesAvailable() > 0)
    

    Und das ganze in einer Schleife. Aber: wenn du DAS machen musst, ist es Bullshit. Lass deinen komischen Thread weg und mach es wie es vorgesehen war.



  • Nun, da in meinem Anwendungsfall durchaus mit mehr Traffic zu rechnen ist, wollte ich direkt mit einer Threaded-Lösung anfangen...

    Über die Event-Q wird ja relativ viel abgehandelt, daher wollte ich eben vermeiden, darüber auch noch den Socket zu erschlagen.

    Aber nun gut. Da das meine ersten QT-Versuche sind, werde ich erstmal die "normale" Lösung nehmen. Wenns dann doch zu fett wird, nehme ich mir die QThread-Variante nochmal vor. Muss ja schließlich irgendwie gehen.



  • Wo siehst du da Probleme? Auch Seitenthreads können eigene Event Loops haben. Solang du nicht wirklich Probleme hast, würde ich da nichts eigenes basteln. Und auch dann erst, wenn du genau verstehst, was das Problem überhaupt verursacht.


Anmelden zum Antworten