[SOLVED] reading data in QTCPsocket is incomplete
-
Hi and thank you for your suggestions !
the thing is :
-
the server is a device and i don't have much information about the TCP message format for the answer. The only thing i know is the response message is composed of :
-
the command the device received + EOL (CR/LF)
-
the answer to the query, here this is the message stored in memory + EOL (CR/LF)
-
state of execution (valid or not) + EOL (CR/LF)
it would be great if the device sends the message size in the TCP frame but i don't have this information.
So i don't know how to be sure i read all data !
I will try to get the number of bytes written to the device as suggested.
Could the EOL (CR/LF) be a problem when reveiving TCP packets ?
How can i handle this ?thanks a lot
-
-
[quote author="Marty" date="1392894981"]
- the command the device received + EOL (CR/LF)
- the answer to the query, here this is the message stored in memory + EOL (CR/LF)
- state of execution (valid or not) + EOL (CR/LF)
[/quote]
You already have enough information. Just wait until you receive all three parts of message which are ends with EOL.
-
how would you write this part ?
because in the documentation it says the response always ends with "@ + first letter of the command sent + state (like V for valid or E for error) + EOL".
I tried to detect the character "@" yesterday just for a test purpose but my app froze like in infinite loop while waiting for that character that never arrives.Also, why when i send the command with telnet in a terminal i get the entire answer. How does telnet know when it gets the entire response ?
thanks again
-
@OK your server is a device ,the information you only know the composition of message as response from the server .
Your problem is you are not getting full data from the server(Which is unknown to you) .
You can use QQueue data structure -QQueue <QByteArray>Queue; (in .h file)
QBytearray data=pSocket->readAll();
qDebug() << "Data From Client : " << "\n\n" <<data;
Queue.enqueue(data);while(!Queue.isEmpty())
{
QString str=Queue.dequeue();
QString str=data;qdebug() << str ; str.clear();
}
try it -
yep. will have a look to QQueue.
here is some code.
When i clic a button :
@void ledBar::getStoredMessage(int bank)
{
QString message;
if (bank < 10)
{
message = sendQuery("COP0" + QString::number(bank) + "\r\n");
}
else
{
message = sendQuery("COP" + QString::number(bank) + "\r\n");
}
qDebug() << message;
}@The sendQuery() Method :
@void TCPClient::sendQuery(QByteArray query)
{
if (socket->state() != QAbstractSocket::ConnectedState)
{
qWarning() << "Can't send command : not connected !";
}
else
{
socket->write(query)
}
}
@then my readYread() slot :
@void TCPClient::readyRead()
{
if(socket->waitForBytesWritten(2000) && socket->waitForReadyRead((2000)))
{
timer->start(timeout);
return socket->readAll();
}
}@ -
Is your code compiled ok?
Anyway, let's change your code in following way:
Add some buffer variables in your class
@private:
//....
QString responseTempalte;
QByteArray incommingData;
bool isDataComplete;
//....@
change getStoredMessage(int bank)
@void ledBar::getStoredMessage(int bank)
{
QString message = QStringLiteral("COP%1\r\n").arg(bank, 2, 10, QChar('0'));
responseTempalte = QStringLiteral("@%1%2\r\n").arg(message.at(0));
incommingData.clear();
isDataComplete = false;
sendQuery(message.toLatin1());
qDebug() << message;
}@
and most important part, readyRead slot
@void TCPClient::readyRead()
{
incommingData.append(socket->readAll());
if(incommingData.contains(responseTempalte.arg("V")) ||
incommingData.contains(responseTempalte.arg("E")) )
{
isDataComplete = true;//or emit some signal
}
}@
something like that, i hope didn't forget something important. -
Great i will give it a try !
maybe the best is, if you have time, to have a look at the whole project :
https://github.com/martialgallorini/ledManager
thanks a lot
-
Well i figured it out but i don't understand why !
With
[CODE]socket->readLine();[/CODE]
it reads each complete line.
I tried everything (read(), readAll()...) and NOTHING but readLine() works !
If anybody has a clue why readAll() does'nt make it here...[CODE]
void TCPClient::readyRead()
{
if(socket->waitForReadyRead(2000))
{
QString resp;
while(socket->bytesAvailable() > 0)
{
resp.append(socket->readLine());
}
emit sigTcpDataReceived(resp.toUtf8());
}
else
{
qWarning() << "Waiting for data to read timed out. No data received !";
}
}
[/CODE]Thank you very much to everybody and for your help !