PDA

View Full Version : QTcpSocket



ken536
18th May 2011, 15:00
I have a problem with my TCPSocket. I wan't to send two strings using write.
This is the send code:



tcpClient.write(("derrors;"+item->text(0)).toAscii().data());
tcpClient.write(("werrors;"+item->text(0)+";;true;").toAscii().data());


This needs to send 2 pieces:
"derrors;00001"
and
"werrors;00001;;true;"

But in fact it sends this: "derrors;00001werrors;00001;;true;"
Even if there is a delay between them.
How can I split this up to two parts?

bibhukalyana
18th May 2011, 15:08
Actually i don't know this things.I think that it is sending separately but when you are receiving you read all bytes at a time.So you should add some header and accordingly you extract it in receiver side.

ken536
18th May 2011, 16:52
No, that's not the problem.
I scanned the outgoing traffic on my computer and find out it is really transmittings it in one block.

yeye_olive
18th May 2011, 18:23
In the TCP protocol the exchanged data is a stream of bytes. There is absolutely no guarantee that the received data will be split into the same chunks as the sent data. If you want to preserve such a structure you need to implement your own solution as you would do if you were writing to and then reading from a file. There are two common ways to achieve this:

use a special delimiter sequence (e.g. newline, NUL character), but make sure you escape it were it to occur in the payload,
send the size of the chunk, then the chunk itself.

In your case solution 1 seems most appropriate, since you appear to be using a text-based protocol.

mcosta
18th May 2011, 19:06
You're right.

QAbstractSocket uses a write buffer to reduce network overhead.
To obtain 2 single TCP packets use QAbstractSocket::flush()



tcpClient.write(("derrors;"+item->text(0)).toAscii().data());
tcpClient.flush();
tcpClient.write(("werrors;"+item->text(0)+";;true;").toAscii().data());

yeye_olive
18th May 2011, 19:38
@mcosta

I would not rely on that for several reasons. First, the doc for QAbstractSocket::flush() specifies that it "writes as much as possible from the internal write buffer to the underlying network socket, without blocking"; therefore it would be necessary to wait until all the data be sent before writing the rest. Next, even if you ensured that any pending data be sent before each write(), each such call could generate several packets. Finally, the packets are translated back into a stream on the receiving end, and there is no exact correspondence between packets and data chunks actually read from the socket.

Therefore I would recommend either to implement one of the solutions I mentioned or to choose another protocol than TCP.