QtNetwork - erste Gehversuche brauchen Unterstützung ...



  • Hallo Forum,

    nach einiger Pause versuche ich mich gerade mal an QtNetwork, dazu hab ich mir folgende Beispiele angeschaut kann die Grundlegend auch nachvollziehen ....

    Threaded Fortune Server Example und Trip Planner

    Nun will ich gern die 2 Beispiele Zusammenfügen um auf diesen Grundlagen dann mein Programm mit einbinden, da dort im Idealfall mal mehr wie 2 Leute parallel arbeiten werden. Der Server liest die Daten der Anfrage ja in der Funktion "readClient()" die im 2. Beispiel durch ein connect des Signals "readyread()" aufgerufen wird .... Nun ist mir aber nicht ganz klar, wie ich das in die threaded-Variante einbaue, ichhab das mal so versucht:

    void GaManThread::run()
     {
        QTcpSocket tcpSocket;
        if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
            emit error(tcpSocket.error());
            return;
        }
        connect (&tcpSocket, SIGNAL(readyRead()), this, SLOT(readClient(socketDescriptor)));
    }
    
    void GaManThread::readClient(int socketDescriptor)
    {
        QTcpSocket tcpSocket;
        tcpSocket.setSocketDescriptor(socketDescriptor);
        QByteArray block;
        QDataStream in(&block, QIODevice::ReadOnly);
        in.setVersion(QDataStream::Qt_4_1);
    
        if (nextBlockSize == 0) {
            if (tcpSocket.bytesAvailable() < sizeof(quint16))
                return;
            in >> nextBlockSize;
        }
    
        if (tcpSocket.bytesAvailable() < nextBlockSize)
            return;
    
        quint8 requestType;
        QString from;
        QString to;
        QDate date;
        QTime time;
        quint8 flag;
    
        in >> requestType;
    
        if (requestType == 'S') {
            in >> from >> to >> date >> time >> flag;
            srand(from.length() * 3600 + to.length() * 60 + time.hour());
            int numTrips = rand() % 8;
            for (int i = 0; i < numTrips; ++i)
                generateRandomTrip(from, to, date, time);
            QDataStream out(&block, QIODevice::WriteOnly);
            out << quint16(0xFFFF);
        }
        //tcpSocket.close();
        tcpSocket.disconnectFromHost();
        tcpSocket.waitForDisconnected();
    }
    

    Allerdings erhalte ich im Moment den Fehler

    Object::connect: No such slot GaManThread::readClient(socketDescriptor)
    

    Den socketDescripter übergebe ich, aus der Überlegung heraus, das ja die Funktion auch irgendwie wissen muss, um welchen Socket es sich handelt ....

    Kann mich hier bitte wer auf den richtigen weg stoßen und mich unterstützen ?

    Danke schonmal,
    der Nala

    P.S.:

    Hier noch der Code der gamanthread.h

    class GaManThread : public QThread
    {
        Q_OBJECT
    
    public:
        GaManThread(int socketDescriptor, const QString &fortune, QObject *parent);
        void run();
    
    signals:
        void error(QTcpSocket::SocketError socketError);
    
    private:
        int socketDescriptor;
        QString text;
    
        quint16 nextBlockSize;
        void generateRandomTrip(const QString &from, const QString &to, const QDate &date, const QTime &time);
    
    private slots:
        void readClient(int socketDescriptor);
    
    };
    


  • Hallo
    erstmal ein paar grundsätzliche Sachen zu Qt Signals/Slots.
    Du kannst keine Paramater übergeben.
    Die Paramater in den slots werden wie folgt aufgerufen:

    #include <QObject>
    #include <QCoreApplication>
    #include <iostream>
    using namespace std;
    
    class ClassA : public QObject
    {
    public:
        void emitA(int pA)
        {
            emit signA(pA);
        }
    signals:
        void signA(int);
    }
    
    class ClassB : public QObject
    {
    public slots:
        void slotA(int pA)
        {
            cout<<pA<<endl;
        }
    }
    
    int main(int argc, char** argv)
    {
        QCoreApplication a(argc, argv);
    
        ClassA *cA = new ClassA();
        ClassB *cB = new ClassB();
        QObject::connect(cA, SIGNALS(signA(int)), cB, SLOTS(slotA(int)));
        cA->emitA(5000);
    
        return a.exec();
    }
    

    Es wird niemals funktionieren, wenn das Signal keinen Paramater hat, der Slot aber schon. Es geht einfach nicht.

    Für dich wäre es am besten, wenn du den Paramater von deinem Slot als Klassenvariable definierst, sie vorher setzt und dann in deinem Slot ausliest.

    Und des weiteren verstehe ich nicht, wieso immer alle alles mit Threads machen.
    bei Qt braucht man das nicht. Threads machen nur Sinn, wenn man eine eigene Event loop hat, eine riesen lange Berechnung durchführen muss, oder sonstiges.

    ich hoffe, ich konnte ein bisschen helfen.

    mfg Matogel

    EDIT: Im Übrigen solltest du dich nochmal mit QTcpSocket /QTcpServer auseinandersetzen. So wie du das machst, wird es nicht funktionieren.


Anmelden zum Antworten