PDA

View Full Version : QTcpSocket Misunderstandings



baray98
15th May 2008, 02:58
Hi all,

I Use QTcpSocket to sendrequest to a device and in turn that device will answer, and I should not send another request until that device has all its reply sent.

Request are small messages like max of 20 bytes but reply can vary from 10 000 to 30 000 bytes.

Reply is stuctured by blocks and a reply may contain several blocks


so I connected QTcpSocket::readyRead() signal to my readData slot (see below for readData slot implementation




void Myclass::readData ()
{
QByteArray incomingBlock;
while (m_deviceLink->socketMscope->bytesAvailable()) // I am suppose to suck all the reply with this
{
QByteArray packet = m_tcpSocket-> readAll();
// append new data to block buffer
incomingBlock.append(packet);

// check if its atleast a header
if ( incomingBlock.count() > (int) sizeof(t_blockHeader))
{
m_response = *(t_blockHeader*)incomingBlock.constData();
if (!isChecksumValid((uint8*)&m_response,sizeof(t_blockHeader))) // a header has checksum to verify its validity
{
emit errorCheckSum();
incomingBlock.clear();
break;
}
if (incomingBlock.count() == (int)(sizeof(t_blockHeader+m_response.dataLength))
{
// i got one block (header + data ) so I am suppose to proccess this then throw away the copy of the received socket data.
m_incomingBlock.clear();
}
else if (m_incomingBlock.count() > (int)(sizeof(t_blockHeader)+ m_response.frameLength))
{
//I am expecting some more burst of data from the socket since some blocks are unfinished but processed the first complete block and trimmed incoming buffer
m_incomingBlock = m_incomingBlock.mid(sizeof(t_blockHeader)+ m_response.dataLength);
}
else
{
// do nothing since received bytes is not even equal to one block
}
}

}
emit readyForData(); //this will signal my requester class to send another request


So, I expected to have all my reply after the while loop but I was wrong my while exited halfway of the transmission of the reply

Now, My Question is how can i suck all the large messages before exiting my while loop?

I guess my payLoad of data is governed by tcpSocket buffer size, So I won't expect reply from the other side to be in one single shot of payLoad.

aamer4yu
15th May 2008, 09:08
check the data for some ending condition...
something like...


do
{
data += socket->readAll();
} while (data.contains(somecondition));



Hope u got the idea

wysota
15th May 2008, 09:35
The fact that some data is available to read doesn't yet mean that all data is available, thus it is not enough to check if something is waiting to be read. You have to have a way to determine if you received a whole reply or not. You can base it on time but this is a flawed approach as lags can cause your timer to timeout before all of the data goes through the link or you can base it on the contents of the data received - like suggested in the previous post.

baray98
15th May 2008, 20:00
I made it event and time driven and it seems to work.