Sockets & Network Programming

message framing

If TCP hands you one long unbroken stream of bytes, how do you know where one message ends and the next begins? It is like receiving a paragraph with no spaces or punctuation — you need some agreed rule to chop it into words. Message framing is exactly that agreed rule: a convention, written into your application protocol, that marks the boundaries of each logical message inside the byte stream.

There are two classic techniques. The first is a length prefix: before each message you write its size, say a 4-byte integer, so the receiver reads those 4 bytes, learns the message is N bytes long, then reads exactly N more bytes — no guessing. The second is a delimiter: you end each message with a special marker that cannot appear inside the data, such as a newline for line-based protocols, and the receiver reads until it sees that marker. Many real protocols combine ideas: HTTP/1 uses a newline-delimited header section, then a Content-Length header (a length prefix) for the body. The receiver must loop and accumulate bytes until it has a full frame, because a single recv may deliver a partial message or several messages at once.

Why it matters: framing is not optional decoration — without it, a TCP-based protocol is simply broken, because the byte-stream abstraction erases your boundaries. Get it wrong and you read half a message and the start of the next, garbling everything after. Framing also has security weight: trusting a length prefix blindly lets an attacker send a huge number to make you allocate enormous memory, so robust code caps the maximum frame size. Delimiter framing must handle the marker appearing inside payloads (via escaping) or it corrupts on legitimate data.

Length-prefix framing: to send "hello" (5 bytes), you first write the 4-byte length 5, then the 5 bytes. The receiver reads 4 bytes (gets 5), then reads exactly 5 more — and knows it has one complete message, no matter how recv split the underlying stream.

Length prefix or delimiter — pick one so the receiver can split the stream.

Always cap a length prefix to a sane maximum. Blindly allocating whatever size the sender claims is a classic denial-of-service hole: one message saying 'length = 4 GB' can exhaust your memory.

Also called
framingdelimiting messageslength-prefix framing訊息分界封框