Qt-interest Archive, April 2007
stream extraction, sockets, and QDataStream blocking question
Message 1 in thread
Hello,
I'm trying to send largish amounts of data over a QTCPSocket using a
QDataStream for serialization at both ends. The data is stored in a
QByteArray.
My question is: Is there a way to make the >> and << operators block
until *all* of the data has been processed?
The docs for QDataStream mention:
"Warning: If you use QSocket or QSocketDevice as the I/O device for
reading data, you must make sure that enough data is available on the
socket for the operation to successfully proceed; QDataStream does not
have any means to handle or recover from short-reads."
But surely waiting for the right amount of data to become available is
the responsibility of the >> operator in the class involved? (I've
looked at the source code for QByteArray, and it doesn't do this...)
Alternatively, can I tell how many bytes a particular data type will
take up on the network before I send it? That Way I could send the
number of bytes to expect, and block until that number of bytes becomes
available.
Am I missing something really obvious here?
--
[ signature omitted ]
Message 2 in thread
On Apr 4, 2007, at 11:00 AM, Thomas Richards wrote:
> I'm trying to send largish amounts of data over a QTCPSocket using a
> QDataStream for serialization at both ends. The data is stored in a
> QByteArray.
>
> My question is: Is there a way to make the >> and << operators block
> until *all* of the data has been processed?
The operators don't have enough information to know if it would be OK
to block, or when there is enough data.
The common way to handle TCP data streams is to create a circular
buffer and share it between a consumer thread and a producer thread.
The producer simply adds data as it gets it from the socket. The
consumer pulls data from the buffer, blocking until data is
available. Look to either semaphores or condition variables to signal
the consumer when data is available. I'm pretty sure Qt includes some
examples that cover these points.
Brad
--
[ signature omitted ]
Message 3 in thread
>
> The operators don't have enough information to know if it would be OK
to
> block, or when there is enough data.
>
Ignoring for the moment the idea about being 'OK' or not to block...
I don't understand how the operators don't have enough information. Take
QRect as a simple example. The operators know to expect the following
information:
* left (qint32)
* top (qint32)
* right (qint32)
* bottom (qint32)
Surely the >> should block until 16 bytes of data are available? I can't
think of a situation where you'd *want* the operator to bail out early..
Again, I get the feeling I'm missing something here..
> The common way to handle TCP data streams is to create a circular
buffer
> and share it between a consumer thread and a producer thread. The
producer
> simply adds data as it gets it from the socket. The consumer pulls
data
> from the buffer, blocking until data is available. Look to either
> semaphores or condition variables to signal the consumer when data is
> available. I'm pretty sure Qt includes some examples that cover these
> points.
>
At the moment I'm attempting to send the amount of data expected as a
quint32, then the data itself. At least this way I can block in a loop
until all the data arrives, although it's pretty ugly, and wastes 4
bytes every network message :(
--
[ signature omitted ]