TCP gives you bytes, not messages
A TCP socket is a continuous byte stream, so two messages sent separately can arrive glued or split — prefix each message with its length so the receiver knows where it ends.
We said greet("Ada") travels as bytes over the wire — but the wire is a TCP stream that doesn't respect your message boundaries, so before anything else the receiver has to be told where one message stops.
Scene 02
TCP gives you bytes, not messages
- Watch
- Try it
- Predict
- Capture
Here's the bug every first network program hits. A TCP socket (the connection your two machines talk over) is not a stream of messages — it's a byte stream: a single, continuous run of bytes with no markers between one message and the next. The client fires two calls back-to-back, greet("Ada") then greet("Bob"). Watch the server's recv() (the call that reads bytes off the socket): one read can return "Ada" plus half of "Bob" — the boundary you sent is simply gone. The receiver needs a way to recover where each message ends; the scheme that does that is called framing — any rule that marks message boundaries on the wire. The simplest framing is length-prefix: write each message's length first, then its bytes, so the reader can read the length and then read exactly that many bytes.
Highlighted lines are the ones running in the diagram right now.
def send(sock, payload):# 4-byte big-endian length, then the bytesheader = len(payload).to_bytes(4, 'big')sock.sendall(header + payload)send(sock, b'Ada') # -> [00 00 00 03] Adasend(sock, b'Bob') # -> [00 00 00 03] Bob
def handle(sock):# one read, however TCP chopped the streamdata = sock.recv(1024)return parse(data) # whatever bytes landed
def readN(sock, n):buf = b''while len(buf) < n: # loop across recv() callsbuf += sock.recv(n - len(buf))return bufdef readFrame(sock):header = readN(sock, 4) # the length prefixlength = int.from_bytes(header, 'big')return readN(sock, length) # exactly one message
Where this sits in Build a gRPC-style RPC framework
Scene 02 of 14, in the The wire act — Bytes, frames, and the schema that gives them meaning.. TCP is a byte stream, not a message stream: two messages can arrive glued or split. A length prefix is what lets the receiver read exactly one message back.
Up next. Now we can recover one whole message — but it's still an opaque blob; the next job is agreeing on what the bytes inside the frame actually MEAN to both sides, in every language.
All 14 scenes in Build a gRPC-style RPC framework · Every curriculum