PDA

View Full Version : QTextStream setup for networking?



invictus
22nd February 2008, 19:30
Hi

When using sockets with signals and slots on the mainthread and the use a QTextStream for interpreting a text protocol from the network (but the question is rather generic so I guess it may apply to other kinds of streams like XmlStream and DataStream as well):

1) When should I create the stream object? Not during each readyRead() signal I assume since this would create a new object for each piece of data (I did see an example where this was used)? Perhaps during connect() and destroy it when disconnect() arrives?

2) When the QTextStream object in created, how should I read the data? Should I wait for the readyRead() signal and then call stream.readLine() for reading a line? I would think this is a blocking operation and therefore would block the entire gui-thread if there are no complete line available at the time of the readyRead() signal emission. Or perhaps the streams got some fancy features for handling just this? I am sure I cant be the first to wonder about this...

I would highly appreciate some help on this. I am used to (from Java) just use the blocking operation and throw everything into a new thread, but since thread synchronization is a bitch and you in QT got this sweet signal to let you know when there is more data...

Thanks!!

wysota
23rd February 2008, 08:58
1) When should I create the stream object?
Whenever you see fit.It's best to create it when the device it operates on is created and keep the stream until the device is destroyed.


2) When the QTextStream object in created, how should I read the data? Should I wait for the readyRead() signal and then call stream.readLine() for reading a line?
If you want to read lines, there is no sense to use the stream. It such case use QIODevice::readLine() instead.


I would think this is a blocking operation and therefore would block the entire gui-thread if there are no complete line available at the time of the readyRead() signal emission.
No, it would return an empty line. If you want to read line by line, don't use QTextStream. Use the API QIODevice and its subclasses offer.

invictus
23rd February 2008, 14:31
Whenever you see fit.It's best to create it when the device it operates on is created and keep the stream until the device is destroyed.

Ok. Will the stream object become useless when the socket is disconnected (after a connection) and thus needs to be re-initialized if I want to reconnect?


If you want to read lines, there is no sense to use the stream. It such case use QIODevice::readLine() instead.

What about if I dont want to read a line, but rather use XML either through SAX or an XML stream? I guess the same problem is valid for this case. The problem is of a general nature: What if I want to read something from a _stream_ connected to a socket. Will it block the thread?

wysota
23rd February 2008, 17:57
Ok. Will the stream object become useless when the socket is disconnected (after a connection) and thus needs to be re-initialized if I want to reconnect?
The stream operates on the underlying device. If the device has data to be read, the stream should work fine. Thus when you reconnect (which means reopening the device) the stream will be able to read/write data.


What about if I dont want to read a line, but rather use XML either through SAX or an XML stream?
Then you don't need a text stream. It's useful only if you want to read separate words. If you want to use Qt classes, all of them will take a QIODevice as its parameter. See QDomDocument::setContent for an example.

What if I want to read something from a _stream_ connected to a socket. Will it block the thread?
No, it will tell you there is nothing to read.

invictus
23rd February 2008, 23:47
So if I connect a QXmlStreamReader to the socket and in the readyRead() slot I use the reader.readNext() it won't block even though there are no "complete" token to read next in the buffer? I hope it won't say that it's the end of the stream :p

wysota
24th February 2008, 00:23
So if I connect a QXmlStreamReader to the socket and in the readyRead() slot I use the reader.readNext() it won't block even though there are no "complete" token to read next in the buffer? I hope it won't say that it's the end of the stream :p

It will probably return an invalid or no token.

I suggest you read all data and concatenate it to a string and then pass the whole string to the xml reader. Of course unless you implement a complex and complete handler for the xml. In such situation you should handle cases where the xml you read is invalid or incomplete so you can't really perform any actions until you read until the end of the xml stream. You can build a syntax tree or something like that and "execute" it when you read the whole xml document though.