PDA

View Full Version : how to peek at serialized data from QDataStream



jmenda
22nd May 2011, 16:56
Hello,

I am adapting networking code from Fortune client and Fortune server examples in Qt 4.6 documentation for my needs, code for reading data looks like this:


QDataStream in(tcpSocket);
quint16 blockSize;
in.setVersion(QDataStream::Qt_4_0);

if (blockSize == 0) {
if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
return;

in >> blockSize;
}

if (tcpSocket->bytesAvailable() < blockSize)
return;

QString nextFortune;
in >> nextFortune;


sending data on the server like this:


QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
...
clientConnection->write(block);


it's quite simple and elegant,server attaches quint16 number,size of the data at the beginnig of each network message,then client reads it only when all of the data is available. however,it first reads the block size which removes it from the socket's buffer and i would like to just peek at the block size and leave it in the buffer.
My problem is,using QTcpSocket.peek() gives me access to the raw data,not to the serialized quint16 blockSize at the begining of the received data buffer. So,is there any proper way to peek at serialized data from QDataStream? Or is it a good idea to insert block size at the server side as raw data?
I could live without it,but it would somewhat complicate my code.
Thanks in advance for all answers.

wysota
22nd May 2011, 22:09
Why do you want to leave the block size in the buffer? Read it and store it in a variable so that you can reuse the value when needed.

jmenda
23rd May 2011, 17:33
Why do you want to leave the block size in the buffer? Read it and store it in a variable so that you can reuse the value when needed.

well,on the server,that would require storing the block size value for every connected socket to a client and i wanted to avoid that so i would have simpler code..but other requirements force me to complicate things anyway,so it won't be a problem now..still it would be nice to be able to peek at serialized data. of course it wouldn't be a problem on a client with single socket to server..i might have not formulated my needs properly (*embarrased*)

wysota
23rd May 2011, 17:35
well,on the server,that would require storing the block size value for every connected socket to a client
I'm sure that's the least of your problems. I'd worry more about exposing your server to DOS attacks which is what you already do.

jmenda
23rd May 2011, 18:24
By sending some very large value as block size? Or is there some other problem as well? It's just skeleton example code but I'll appreciate any thoughts about it's limitiations or errors.

wysota
24th May 2011, 00:51
By sending some very large value as block size?
Yes, that's one of the problems. Receiving bogus data in the block itself is another problem. QDataStream as a network protocol is much over advertised.

jmenda
24th May 2011, 03:53
Receiving bogus data in the block itself is another problem. QDataStream as a network protocol is much over advertised.
Checking for validity of correct type of data is my application's problem. And I understand from the documentation,that corrupted data should change QDataStream's status to QDataStream::ReadCorruptData.. so what other problem there could be? I assume possibility of buffer overflow,etc. is taken care of by qt developers.

wysota
24th May 2011, 09:45
Checking for validity of correct type of data is my application's problem. And I understand from the documentation,that corrupted data should change QDataStream's status to QDataStream::ReadCorruptData.. so what other problem there could be?
That you lose sync with the stream and the only thing you can do is disconnect the client. Besides, nobody checks the status of the stream anyway.


I assume possibility of buffer overflow,etc. is taken care of by qt developers.
There is no buffer overflow. Clients can just crash your machine by feeding it more data that the machine has RAM available while often you wait just for a few bytes of data. It is a rare case that your server works on generic data, usually you have some kind of protocol and you know how much data to expect. Relying on the client to provide a size followed by a blob is just asking for trouble.