Seite 1 von 1

Konzeptpr.:QThread,QTcpSocket - Verbinden sobald Host da ist

Verfasst: 22. September 2010 14:19
von rubikon
Moin.

Meine WinCE Anwendung soll zu einer Hostanwendung eine Socket Verbindung aufbauen. Meine Anwendung soll als Client fungieren.

Nun kann es aber sein, dass die Hostanwendung später gestartet wird als meine Clientanwendung.

Deshalb habe ich versucht einer Art Pollen (im seperaten Thread) zu implementieren. Da ich gerade mit dem Signal/Slot Prinzip noch nicht so vertraut bin, stoße ich schnell auf Probleme.

Das habe ich bis jetzt gemacht:

Code: Alles auswählen

class QSocketEngine : public QThread
{
    Q_OBJECT

    private:
        QAbstractSocket *m_pTcpSocket;

	private slots:
        void SocketStateChanged(QAbstractSocket::SocketState socketState);
        void displayError( QAbstractSocket::SocketError socketError);
        void ReadFromSocket();

    protected:
        void run();

    public:
        explicit QSocketEngine(QObject *parent = 0);
};

Code: Alles auswählen

QSocketEngine::QSocketEngine(QObject *parent) :
    QThread(parent)
{
    // neuen Tcp-Socket erstellen
    m_pTcpSocket = new QTcpSocket();

    //--- Objekt in diesen Thread 'verschieben'
    m_pTcpSocket->moveToThread(this);

    connect(m_pTcpSocket,   SIGNAL(readyRead()),
            this,           SLOT(ReadFromSocket() ) );
    connect(m_pTcpSocket,   SIGNAL(error( QAbstractSocket::SocketError)),
            this,           SLOT(displayError(QAbstractSocket::SocketError) ), Qt::DirectConnection);
    connect(m_pTcpSocket,   SIGNAL(stateChanged(QAbstractSocket::SocketState)),
            this,           SLOT(SocketStateChanged(QAbstractSocket::SocketState)), Qt::DirectConnection);
}

void QSocketEngine::run()
{
    static int nConnect = 0;

    qDebug() << "Thread begin";

    do
    {
        qDebug() << "PollForServer - Try Nr" << nConnect;
        nConnect++;
        blockSize = 0;

        // Falls in Verwendung, Socket zurücksetzen
        m_pTcpSocket->abort();

        // Mit dem Server verbinden
        m_pTcpSocket->connectToHost("192.168.1.1", 4000);

    }
    while(!m_pTcpSocket->waitForConnected());

    qDebug() << "Thread end";
}

void QSocketEngine::SocketStateChanged(QAbstractSocket::SocketState socketState)
{
...
...
Nun kann ich anhand der Slots stateChanged() und SocketStateChanged() erfolgreich gepollt wird:
PollForServer - Try Nr 1
SocketStateChanged (Thread) QAbstractSocket::HostLookupState
SocketStateChanged (Thread) QAbstractSocket::ConnectingState
SocketStateChanged (Thread) QAbstractSocket::UnconnectedState
SocketError (Thread) QAbstractSocket::ConnectionRefusedError
PollForServer - Try Nr 2
SocketStateChanged (Thread) QAbstractSocket::HostLookupState
...
...
Wenn ich nun die Hostanwendung starte, sehe ich dass die Verbindung erfolgreich etabliert wurde:
SocketStateChanged (Thread) QAbstractSocket::ConnectedState
Thread end
Der Thread 0x7f40096 hat mit Code 0 (0x0) geendet.
Nur kann ich aber keine Daten empfangen, da sich der Thread beendet und der Slot readyRead() nicht mehr funktioniert.

Wie kann ich das Problem lösen?

Es soll im zweiten Schritt auch so sein, dass wenn die Hostanwendung geschlossen wird, das Pollen wieder gestartet wird, damit bei einem erneuten Starten wieder eine Verbindung etabliert werden kann.

Vielen Dank

Verfasst: 22. September 2010 18:07
von Christian81

Verfasst: 23. September 2010 10:54
von RHBaum
Nur noch als Tip.

Bei windows, ich nehm an bei CE wirds aehnlich sein, reagieren die Sockets bei timeouts "komisch". Bei mir zumindest.
Das heisst bei mir versuchen sie ca. X sek lang verbindung aufzubauen.
Und erst nach Y Sekunden wird der Fehler (timeout) gesetzt und der connect kehrt zurueck.
Wobei Y ein vielfaches von X ist.

Besser: gleich nur bestimmte Zeit auf den connect zu warten, und immer gleich wieder probieren. waitForConnected sollte da weiterhelfen, anstatt auf error zu reagieren, vielleicht.
(ich hab die winsock immer direkt benutzt).

Ciao ...