T
T
Travious2016-08-19 16:18:51
Network administration
Travious, 2016-08-19 16:18:51

How to determine that a new package has started and the previous one has ended?

Let's say the client sends something to the server, and the server reads in a while loop or asynchronously (BeginRead/EndRead).
And now 2 different messages from the client pass without any gap.
That is, from the client side, it looks something like this:

var tcp = new TcpClient(...);
...
var sr = tcp.GetStream();
sr.Write("{'json_example': 'Apple'}"); //первое сообщение
sr.Write("{'json_example': 'BananaAvocado'}"); //и прямо тотчас же второе

Actually the question is: how can the server determine that one message has ended and the second has begun?
The decision came by itself: before sending the data itself, first send the length of this very data so that the server knows how many bytes to read and after how many bytes a new packet will start.
Or even simpler: just enter a fixed packet size, say 1024 bytes.
But I, as usual, am dissatisfied with everything and again I see a crutch in my decision.
Is there any way to avoid this "crutch"? Maybe .NET already has a ready-made implementation of such a class? Or is everything okay?

Answer the question

In order to leave comments, you need to log in

4 answer(s)
M
Mercury13, 2016-08-19
@Mercury13

TCP considers data to be a continuous stream; everything that did not come was asked again, everything that came out of turn was put in its place.
The only way is to create artificial packet boundaries in this data stream. For example:
opcode : word
packetLength : dword
data : byte[packetLength]

S
Stanislav Makarov, 2016-08-19
@Nipheris

As Mercury13 already noted, TCP gives you a "virtual wire" where there are no packets anymore, and this is its (TCP) convenience.
Application protocols over TCP always define in one way or another how to send messages of known length, or how to determine the end of the current message and the beginning of the next. Your method is
is more than standard for binary protocols, and not at all a crutch. You can’t think of another reliable way for binary data (which is why, by the way, the null terminator in Sish strings is not a good idea in principle).
For text or mixed protocols, other approaches may be used. For example, in the same HTTP, in the simplest case, headers are read up to the first double \r\n, and then as many bytes as specified in Content-Length are read.
In your case, if you are passing JSON, which will still be parsed (because JSON is a text protocol, not binary, and the start-end of the message in it is determined by the syntax , and not by a pre-transmitted length), then you can use one of the JSON Streaming conventions. More convenient and safer is Concatenated JSON , but then the parser you use must be smart enough to stop in time when reading the value from the stream. Then you can simply read all the transferred objects in a row from the stream.
PS I'm not sure if you have JSON anymore, because you have a single quote in your message.

V
Vladimir Dubrovin, 2016-08-19
@z3apa3a

If you are transferring data over HTTP, use chunked encoding and transfer data in HTTP chunks, they use exactly this structure (passes the size of the chunk, then the chunk itself).

S
Stanislav Silin, 2016-08-20
@byme

.net has things like BinaryReader and BinaryWriter . If you send a string to the writer at one end, then the reader at the other end will wait until it has read the entire string. If there are multiple lines, they are counted sequentially.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question