My question is more general to network programming, but because I’m trying to write a Modbus TCP server (slave), I will use it to illustrate my question.
In a Modbus TCP frame, the 5th and 6th byte of the frame give the size of the frame:
bytes 1 & 2: Transaction Id
bytes 3 & 4: Protocol Id
bytes 5 & 6: How many bytes remain in the frame
bytes 7 – n: The rest of the frame.
When using NetworkStream.Read()/BeginRead(), how can I delimit the received frames?
I’ve seen some open source implementations that just read the first 6 bytes, parse bytes 5 and 6 to get the size of the rest of the frame, and then read the rest of the frame. But if you don’t have start and end delimiters in your frame, how do you know where the frame begins and ends?
For example, maybe the client sent a few garbage characters, then sent a good frame. In this case if I just read the first 6 bytes, I’ll miss the good frame, and possibly future frames because I’m out of sync with the rhythm of the client.
This question isn’t really specific to Modbus, but to any protocol that uses a “size” field to specify the size of the frame. How do you delimit the frames?
I feel like I’m missing something fundamental to network programming, but maybe the protocol is just not well-designed.
Clients are not supposed to send garbage characters in most Internet protocols: If a client sends garbage, the server will send an error and close the connection. If the client wants to continue communicating with the server, it needs to create a new connection and behave properly this time.
There a some protocols that use a Self-synchronizing code. This allows a recipient to find the start of the next frame from any position within the stream.