QTcpSocket this::write() — how to guarantee the data transmission in one package?

Good afternoon.


I am a novice in network programming, but still.


Write a client-server system. Qt is the qt client and the server. The client sends a request (json), the server processes the request and generates a json response.


On the server side, data sending is implemented using the method socket-> write(data) where data is a string.


On the client side when retrieving data, the method is called slotReadyRead () connected to the signal readyRead().


Data is read by the method socket->readAll().


But here's the problem, when the server sends a small string, the client accepts it completely. If you see a great line (great Jason), the string parts. That is, a single call to signal readyRead does not mean getting the FULL message from the server, as I understand it. Hence the question, as at once to convey a BIG string?
October 3rd 19 at 03:12
4 answers
October 3rd 19 at 03:14
No way. TCP is stream data, it is not broken into messages. When you need them, passed first the length, then the body of each new message.
October 3rd 19 at 03:16
No way. There is such a thing called MTU . The package cannot be greater than MTU in principle (usually about half a kilobyte).
In any case you need the upper layer Protocol to communicate the message and not the thread (in principle you can certainly parenthesis to count, but this is not a solution). Often messages leave the line that are guaranteed not to get into the data or transmit the message size.
PDA a beginner I would recommend qtWebsocket.
Still don't understand. If I give first, the message size (the length of the string), and it will be transferred not completely, what will change?

Thank you for the link. I see. - wilfred_Schinner59 commented on October 3rd 19 at 03:19
October 3rd 19 at 03:18
and it is not transmitted completely, what will change?
changes is that You will know that the data has not all arrived, and need to read more.

Seriously — look at cutewebsite, they flows a good friend and another 100 there are. I once mess to beat the students hands over the curves of solutions with raw tcp.
OK. Well at least there is someone on hand to beat and say "but but." Thanks again - wilfred_Schinner59 commented on October 3rd 19 at 03:21
still thought and decided the issue in the following way: on the server side when sending message to add a line terminator. on the client side when receiving a message, do:
QString response;

while(1)
{
 response += QString(m_pTcpSocket->readAll());

 if (response.contains("\n"))
{
break;
 } else
{
m_pTcpSocket->waitForReadyRead(100);
}
}


is this correct — I don't know. but it works. - wilfred_Schinner59 commented on October 3rd 19 at 03:24
If along with the end of the line will come something? And in qt reading from the socket is easier to implement using the signal\slot. - wilfred_Schinner59 commented on October 3rd 19 at 03:27
If along with the end of the line will come something? will ku. To share this character. And before the next reading to consider the tail of the beginning of the next line.
And in qt reading from the socket is easier to implement using the signal\slot.
That's a good idea. I'm actually surprised that the person writing to qt, uses a blocking read. - jace commented on October 3rd 19 at 03:30
About signal/slot, and implemented. This cycle starts in the slot connected to readyRead. But the expulsion of the signal readyRead does not guarantee the delivery of the entire message (ie json), and says only that came the first portion of the data, and the rest have to wait.

About "if the end of the line will come something else". In my case, not coming. The server responds to client requests and own nothing to send. That is, transmitted one message, not multiple messages separated by newline - Lilla99 commented on October 3rd 19 at 03:33
October 3rd 19 at 03:20
Take a platform-independent data type. For example quint64.
Calculate the size of message, store in a quint64.
Refer this variable then the message.

On the other end:
if(bytesAvailable() < sizeof(quint64)) return;

If more read quint64, which will be the size of the next message. Well, wait until the remaining bytes >= the values obtained.

And better data is serialized using QDataStream
Using datastream is not an option. Since the server communicates not only the qt client. But the Java client (Android). And to understand the format of the datastream does not want - wilfred_Schinner59 commented on October 3rd 19 at 03:23

Find more questions by tags QtSockets