PDA

View Full Version : Trouble with QTcpSocket



GabrielGray
30th June 2010, 16:34
Good afternoon,
I am using QTcpServer and QTcpSocket in my application to transfer data, mainly text.
So, the problem appears when i try to send very fast multiple packets.

As an example:

The server needs to send text like this:

stream << numberOfStringsToSend;
for(int i = 0; i < numberOfStringsToSend; i++){
stream << textForThisIteration(i);
}

It seems to be sending everything, but the client doesn't receive it properly. In the client i can get as much as no packet at all or i can get everything correctly, its almost random. Im using the readyRead signal to read from the socket with a QDataStream.

Any hint to solve this problem would be apreciated :x The only way i can think to bypass this, would be sending all the packets in one, but cmon, there must be a way to send packets whenever i want and grant they arrive properly :x

Thanks

tbscope
30th June 2010, 16:59
You can send whatever, whenever you want with QTcpSocket.

From your post I understand you use the readyRead() signal. That's already a good idea. But how do you read the data in the slot connected to the readyRead signal?

Do you use readAll and assume that it read the complete response sent by the server?

GabrielGray
30th June 2010, 17:07
My logic is:

When i send a packet in the server, i do it by sending a QString through the QDataStream
When i receive that packet in the client, readyRead is emitted and my slot gets a QString from the QDataStream

This way i think i always fetch the last QString sent. Still what you said makes sense, because readyRead() could be triggered once, and a few QStrings were received, and by reading only one, the buffer is cleaned before i fetch the rest, am i right?

tbscope
30th June 2010, 17:17
This way i think i always fetch the last QString sent. Still what you said makes sense, because readyRead() could be triggered once, and a few QStrings were received, and by reading only one, the buffer is cleaned before i fetch the rest, am i right?

You're on the right path :-)

I remember that I was debugging a program that received data via a QTcpSocket and I didn't get any data in my own buffer.
What happened was that the readyRead signal can be emitted without any data, in my case, it received something but it then got another readyRead signal with zero data. The way I implemented the slot I always reseted my own buffer. In the end, my own buffer was either empty or it contained something (if I was lucky enough to not get an empty readyRead).

The protocol I implemented contained a control character to signal the end of a datastream.
Thus to solve the problem I kept adding to my own buffer every time the readyRead() signal was fired until I got that end of stream character.

You can do something similar. You know the number of strings you send (and the client too). I would take advantage of that information to see if I got everything.

GabrielGray
30th June 2010, 17:40
Thanks , it was very useful, i solved it, that was the problem exactly.
readyRead() was emitted, and i went to get only one QString, the others were ignored, in order to solve it i did:

while(!stream.atEnd() ){
stream >> packet;
handlePacket(packet);
}

Thanks!