QTcpSocket and data size - how do I know the size?
I have a client/server application and I am confused about how the receiving side knows when enough data is available.
The sender (which may be client or server) will send a single char to indicate mode, then a list of elements being requested or returned.
for instance, if the client wants to request some variables from the server, it does something like:
Code:
void class::sendData()
{
QChar c
('v');
//indicate this is a variable request with 'v' char. QStringList varlist
("var1") <<
"var2";
//indicate the list of vars being requested.
out << c;
//out << dataSize //how do I calculate this value?
out << varlist;
socket->write(block);
}
how does the receiving side know when enough data is available? In the fortune examples, it writes the size of the string in the first bytes, which is fine for a single string.
But how do I know the size of a QStringList? is it just the sum of the lengths of the strings, or is there a sizeof command which calculates it?
After the request has been made, the recipient would respond with something like:
Code:
void class::sendData()
{
QChar c
('V');
//indicate this is a variable response with 'V' char. QHash<QString, QVariant> vars;
vars
["var2"] = QVariant("some data here");
out << c;
//out << dataSize //how do I calculate this value?
out << vars;
socket->write(block);
}
of course, the real implementation would fetch the values for the QHash from some other place based on the list previously received, and socket is a class member created from the connection.
The documentation says that QHash is serializable, as well as QVariant, so it tells me that the << operator will do its job, but on the receiving side, how do I know how big the data is?
Do I have to write it to a QByteArray, then measure the size of the bytearray, then write the size of the bytearray, then write the bytearray itself? This seems like an awful lot of copying and buffering that could be avoided if I knew the size (which will always be different) ahead of time. If I am sending a long list of variables, this could be expensive!
I was considering creating a blocking TCP thread instead of returning when not enough bytes have arrived, but this has the same problem, because >> does not seem to block. Is there a way to make >> block, or a way to pre-calculate the size instead of putting it in a bytearray?
thanks!
Re: QTcpSocket and data size - how do I know the size?
Quote:
Originally Posted by
themolecule
how does the receiving side know when enough data is available? In the fortune examples, it writes the size of the string in the first bytes, which is fine for a single string.
Yes, but it does it in a generic way:
Code:
out << (quint16)0;
...
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
As you can see the value written at the beginning of the block is calculated from the block size, so it doesn't matter what you write to the data stream in line 2.
Quote:
Originally Posted by
themolecule
But how do I know the size of a QStringList? is it just the sum of the lengths of the strings, or is there a sizeof command which calculates it?
It depends on the encoding scheme you use. QDataStream will use this one.
Quote:
Originally Posted by
themolecule
Is there a way to make >> block
No, there isn't.
Re: QTcpSocket and data size - how do I know the size?
ok... well, would it work to do something like
Code:
void class::sendData()
{
QChar c
('v');
//indicate this is a variable request with 'v' char. QStringList varlist
("var1") <<
"var2";
//indicate the list of vars being requested. QStringList varlist2
("var1") <<
"var2";
//indicate another list of vars.
out << varlist;
out << varlist2;
socket << c << (quint16) out.size() << out;
}
or does abstractSocketItem not use the << syntax? Is this better, or just equivalent? Is it slow to rewind the pointer in a bytearray?
Re: QTcpSocket and data size - how do I know the size?
Quote:
Originally Posted by
themolecule
or does abstractSocketItem not use the << syntax? Is this better, or just equivalent?
No, it doesn't have operator<<. You have to use QIODevice::write().
Quote:
Originally Posted by
themolecule
Is it slow to rewind the pointer in a bytearray?
It shouldn't be. It's probably just a single assignment.