1

When the socket times out while waiting for a read it occasionally fails. But when it does fail, it continuously fails, and the log message in slotDisconnected never gets reported despite mpSocket's disconnected signal being connected to slotDisconnect(). It's as if the return statement in slotConnected isn't being hit and it's going round in a continous loop.

void Worker::slotDisconnected()
{
    // Attempt to reconnect
    log("Disconnected from Server. Attempting to reconnect...");

    // fires mpSocket's connect signal (which is connected to slotConnected)
    connectToServer();
}

void Worker::slotConnected()
{
    // Loop forever while connected and receiving messages correctly
    while(1)
    {

        if(mpSocket->bytesAvailable())
        {
            // A message is ready to read
        }
        else if(!mpSocket->waitForReadyRead(mSocketTimeOut))
        {
            // waitForReadyRead returned false - instead of continuing and trying again, we must disconnect as sometimes
            // (for some unknown reason) it gets stuck in an infinite loop without disconnecting itself as it should
            log("Socket timed out while waiting for next message.\nError String: " + mpSocket->errorString());
            msleep(3000);
            mpSocket->disconnect();
            return;
        }
    }
}

The signals/slots are connected like so:

connect(mpSocket, &QAbstractSocket::disconnected, this, &TRNGrabberWorker::slotDisconnected);
connect(mpSocket, &QAbstractSocket::connected, this, &TRNGrabberWorker::slotConnected);

Anyone have any idea's what's going on? Would be much appreciated

Nodeocrat
  • 816
  • 2
  • 14
  • 29
  • 1
    You should never block in "normal" Qt thread, be it either with loop like that `while(1)`, or with "convenience" method like `waitForReadyRead()`. Just don't. Use `QTimer` of you need "infinite" repeating action with interval, and connect signals like `readyRead()`. It's a bit tedious, but still, just do it that way (connecting to lambdas can make this a lot easier than in Qt4, though). – hyde Mar 16 '16 at 18:38

1 Answers1

3

To disconnect from server use mpSocket->disconnectFromHost(); instead of mpSocket->disconnect();.

Actually mpSocket->disconnect(); disconnects all signals/slots of object mpSocket.

Evgeny S.
  • 838
  • 4
  • 12
  • Ah, well spotted! :D Still confused as to why the return wasn't being hit though – Nodeocrat Mar 16 '16 at 17:32
  • @Ashley Please, avoid using infinite loops in Qt when you want to work with signas/slots. You'd better emulate loops `QTimer::singleShot()` with zero delay returning to the same slot each next event loop cycle. When you implement your custom infinite loops you are breaking the Qt event loop system. As a workaround, call, at least, `QApplication::processEvents()` on each cycle iteration. – Evgeny S. Mar 16 '16 at 18:20