Why message boundaries matter
TCP provides an ordered byte stream; the sender's write calls do not establish message boundaries for the receiver. A socket read may return part of a frame or several frames. RFC 9293 specifies TCP; an application protocol must define its own framing and validation. UDP is datagram-oriented, but does not guarantee delivery or duplicate protection. See RFC 9293 and RFC 768.
A deliberately small wire format
For this example only, a frame begins with an unsigned two-byte, big-endian payload length, followed by that many payload bytes. The maximum accepted payload is 64 bytes. This is not a JT/T 808, GNSS, or device-vendor wire format; consult the actual protocol before interpreting field traffic.
class Decoder:
MAX_PAYLOAD = 64
def __init__(self):
self.buffer = bytearray()
def feed(self, chunk):
self.buffer.extend(chunk)
frames = []
while len(self.buffer) >= 2:
length = int.from_bytes(self.buffer[:2], "big")
if length > self.MAX_PAYLOAD:
raise ValueError("payload too large")
if len(self.buffer) < 2 + length:
break
frames.append(bytes(self.buffer[2:2 + length]))
del self.buffer[:2 + length]
return frames
wire = b"\x00\x03GPS\x00\x02OK"
decoder = Decoder()
assert decoder.feed(wire[:1]) == []
assert decoder.feed(wire[1:4]) == []
assert decoder.feed(wire[4:]) == [b"GPS", b"OK"]
try:
Decoder().feed(b"\x00\x41")
except ValueError:
pass
else:
raise AssertionError("oversized frame was accepted")
print("all synthetic checks passed")Save as framing_example.py and run python framing_example.py. The assertions cover a split header, a split payload, two frames delivered together and rejection of an oversized declared payload. A zero-length payload is accepted by this toy format; a real protocol may forbid it.
Boundaries before production
The example is intentionally incomplete: it does not authenticate devices, validate checksums, limit the size of each incoming chunk, cap aggregate buffer growth, apply an idle timeout, resynchronize after an invalid header, or persist accepted data. A production implementation needs explicit limits and a tested policy for each of those conditions. If a frame is invalid, close or resynchronize according to the actual protocol; do not silently guess.
Framing alone does not prevent duplicate events. Preserve protocol identity, device or session scope, timestamps and acknowledgement semantics separately, and test replay and restart behavior. Do not use customer telemetry as a public fixture without authorization.
Continue with related tools
- Inspect Modbus and CAN examples in Rootcastle LAB.
- Read the GNSS telemetry ingestion guide for event identity and replay.
- Inspect the public JT808 parser repository and its actual supported format.
Suggested citation
Rootcastle Engineering & Innovation. “TCP telemetry framing, tested with synthetic streams.” https://rootcastle.com/en/projects/guides/telemetry-framing/. Accessed on the date you used the reference.
References
- W. Eddy, ed. RFC 9293: Transmission Control Protocol, IETF, 2022.
- J. Postel. RFC 768: User Datagram Protocol, IETF, 1980; check the RFC Editor page for updates.