While() infinite loop after migrating from Qt 4.8 to Qt 5.4
-
Hello,
I have with my app after porting it from Qt 4.8 to Qt 5.4
My app connects to a led journal over TCP and retrieves / modifies text contents in memory banks. i.e. i send a command like APL01 and the device returns content of memory 1 like so :
APL01 Memory 1 text content here... @CV
I am testing the @ character to find the end of response and parse it.
With my application compiled under Qt 4.8 everything is fine. With Qt 5.4 the app loops forever.
here is the github project page : https://github.com/martialgallorini/ledManager
the code that causes the app to loop is in tcpClient.cpp :
QString TCPClient::sendQuery(QString query) { if (socket->state() != QAbstractSocket::ConnectedState) { qWarning() << "Can't send command : not connected !"; } else { while (socket->bytesAvailable() > 0) // purge socket buffer { socket->readLine(); } socket->write(query.toLatin1()); QString resp; if(socket->waitForBytesWritten(2000) && socket->waitForReadyRead(2000)) // read response { // ISSUE HERE !!! INFINITE LOOP while(socket->bytesAvailable() > 0 || (!resp.contains("@"))) { resp.append(QString::fromLatin1(socket->readLine())); } return resp; } else { qWarning() << "Waiting for data to read timed out. Nothing to read !"; } } return QString(); }
Do you have any idea ?
Seems like the app never gets the @ character. Are you aware of any QString and/or QByteArray character encoding modifications in Qt 5.4 ?
thanks a lot
-
@Marty said:
while(socket->bytesAvailable() > 0 || (!resp.contains("@")))
{
resp.append(QString::fromLatin1(socket->readLine()));
}The Issue is there.
if resp does not contain '@' and bytesAvailable returns <= 0 you never exit from the loop -
Hi,
Yes i know.
Maybe i should add a condition to exit the loop if there is some bug or transmission errors.But the thing is : '@' is expected
I should read it in every response i get from the device. '@' marks the end of every device answer to any command. -
@Marty said:
But the thing is : '@' is expected
In TCP you cannot be sure you receive all data in a single transmission.
You should check you received enough data to be sure '@' is contained -
thanks for the advice.
I will try your suggestions.
Do you think it could be a character encoding issue ?
Like if i read the memory content with the '@' but the app doesn't recognize it as a '@' ? -
I don't think so
-
PS : the device uses CP 1252 character encoding.
How can i be sure to use the same encoding in Qt ? -
Qt internally uses Unicode for QString and QChar.
When you read a text you can useQTextCodec
to handle the right encoding -
Seems to work now
While() loop exit condition doesn’t work because socket buffer doesn’t update automatically. It updates when next waitForReadyRead signal fires. So we need to keep checking if data is still available to read with calling waitForReadyRead.
Changing while() loop to :
QString resp; if(socket->waitForBytesWritten(2000)) { while(socket->bytesAvailable() > 0 || socket->waitForReadyRead(2000)) { resp.append(QString::fromLatin1(socket->readLine())); if (resp.contains("@")) return true; } } qWarning() << "Waiting for data to read timed out. Nothing to read !";
-
I think the key is the waitForReadyRead(). I have run into problems with using the function bytesAvailable() for various unknown reasons.
Maybe something like this might work as well (?):
while(socket->bytesAvailable() > 0 || (!resp.contains("@")))
{
resp.append(QString::fromLatin1(socket->readLine()));
socket->waitForReadyRead(1);
}