2016-03-16 10 views
1

Когда сокет истекает во время ожидания чтения, он иногда терпит неудачу. Но когда он сбой, он постоянно терпит неудачу, и сообщение журнала в slotDisconnected никогда не сообщается, несмотря на то, что отключенный сигнал mpSocket подключен к slotDisconnect(). Это похоже на то, что оператор return в slotConnected не попадает, и он идет в непрерывном цикле.Qt Сигнал и слоты не работают должным образом

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; 
     } 
    } 
} 

Сигналы/слоты связаны следующим образом:

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

Кто-нибудь есть какие-либо идеи, что это происходит? Было бы очень полезно

+1

Вы никогда не должны блокировать «нормальный» поток Qt, будь то с помощью цикла 'while (1)' или с помощью метода «удобства», например 'waitForReadyRead()'. Только не надо. Используйте 'QTimer' вам нужно« бесконечное »повторяющееся действие с интервалом и подключить сигналы типа' readyRead() '. Это немного утомительно, но все же, просто делайте это так (подключение к lambdas может сделать это намного проще, чем в Qt4). – hyde

ответ

3

Чтобы отключиться от сервера, используйте mpSocket->disconnectFromHost(); вместо mpSocket->disconnect();.

Фактически mpSocket->disconnect(); отключает все сигналы/слоты объекта mpSocket.

+0

А, хорошо заметили! : D Все еще смущенно, почему возвращение не было удалено, хотя – Nodeocrat

+0

@Ashley Пожалуйста, избегайте использования бесконечных циклов в Qt, когда вы хотите работать со знаками/слотами. Лучше эмулировать циклы 'QTimer :: singleShot()' с нулевой задержкой, возвращающейся в один и тот же слот в каждом цикле цикла событий. Когда вы реализуете свои пользовательские бесконечные циклы, вы нарушаете систему циклов событий Qt. В качестве обходного пути вызовите, по крайней мере, 'QApplication :: processEvents()' для каждой итерации цикла. –