Framing
Part of Networking
How transmitted bits are grouped into meaningful units — the problem of where one message ends and the next begins.
Why This Matters
A stream of bits traveling across a wire has no inherent structure. The bits 0110100101110011… could be one message, two messages, or twenty messages — there is no way to tell without additional information defining where messages begin and end. Framing solves this problem: it imposes structure on a raw bit stream so the receiver can identify the boundaries of individual messages.
Framing is one of the most fundamental problems in data communication. Every protocol at every layer faces some form of it. Serial ports use start and stop bits to frame bytes. Ethernet uses preambles and length fields to frame packets. TCP uses length fields and sequence numbers to frame byte streams. Understanding framing means understanding how protocols create structure from the chaos of a raw bit stream.
Poor framing creates disastrous failure modes: the receiver loses track of where it is in the bit stream and misinterprets all subsequent data. These desynchronization failures can be silent — the receiver continues accepting data it misinterprets as valid, producing wrong results rather than obvious errors. Understanding framing helps you avoid these failures and diagnose them when they occur.
Asynchronous Framing with Start/Stop Bits
The simplest framing method is used in UART (Universal Asynchronous Receiver/Transmitter) serial communication. Each byte of data is framed individually with a start bit before it and one or two stop bits after it.
When no data is being sent, the line is held at the idle (MARK, logical 1) state. To transmit a byte, the transmitter:
- Drives the line to 0 for one bit period — the start bit
- Sends each of the 8 data bits in order
- Optionally sends a parity bit
- Holds the line at 1 for one (or two) stop bits
- Returns to idle
The receiver detects the falling edge of the start bit (the transition from idle 1 to start bit 0), waits 1.5 bit periods to sample in the middle of the first data bit, then samples every bit period until it has received all data bits and the stop bit.
The critical feature of start/stop framing is self-synchronizing: the receiver resynchronizes its sampling with every byte. If the receiver gets confused (samples at the wrong time due to noise), it can recover at the next start bit. Each byte starts fresh, with no accumulated timing error.
The cost of start/stop framing is overhead: 2 framing bits (start + stop) for every 8 data bits, reducing efficiency to 80%. This is acceptable for low-speed links but wasteful for high-speed communication.
Synchronous Framing with Flags
For higher efficiency, synchronous framing sends data continuously without per-byte framing bits. Instead, a special bit pattern (the flag) marks the beginning and end of frames.
HDLC (High-Level Data Link Control) uses the flag 01111110 (0x7E) to delimit frames. A frame begins when the receiver sees this pattern and ends when it sees it again. But what if the data itself contains 01111110? The receiver would mistake the data for a frame boundary.
Bit stuffing solves this: the transmitter inserts (stuffs) a 0 bit after any run of five consecutive 1 bits in the data. This ensures that 01111110 never appears in the data stream — the maximum run of 1 bits in transmitted data is five, followed by a stuffed 0. The receiver removes (destuffs) the 0 bit after every five consecutive 1 bits in the data.
The flag 01111110 contains six consecutive 1 bits, which is impossible in stuffed data — the receiver can therefore unambiguously identify the flag. Bit stuffing adds, on average, about 0.4% overhead for typical data, much less than start/stop framing.
Length-Prefixed Framing
The simplest framing for protocols built on reliable byte streams (like TCP): each message is prefixed with a field containing the message’s length. The receiver reads the length field, then reads exactly that many bytes to get the complete message.
Example: if each message is prefixed by a 2-byte length field, the receiver reads 2 bytes to get the length (say, 1024), then reads exactly 1024 bytes to get the message body, then reads 2 bytes for the next length, and so on.
Length-prefixed framing is simple, low-overhead (just 2-4 bytes per message), and handles arbitrary binary data without any stuffing or escaping. Its weakness is that the receiver must know the length before reading the message. For variable-length messages without a known maximum size, the receiver must have a buffer large enough for any message, or the protocol must impose a maximum message size.
Length fields must be interpreted carefully. A 2-byte unsigned length can express 0 to 65535. If a buggy sender transmits a malformed length field, the receiver will attempt to read that many bytes, potentially blocking indefinitely waiting for data that will never arrive. Robust implementations include maximum message size limits and timeouts.
Delimiter-Based Framing
Delimiter-based framing uses a special byte sequence to mark the end of each message. HTTP request headers end at the sequence CRLF CRLF (\r\n\r\n). Lines of text end at \n or \r\n. These are familiar, human-readable framing mechanisms.
The weakness of delimiter framing is the same as flag-based framing: the delimiter cannot appear in the data without escaping. HTTP solves this for headers by defining headers as text only, but for binary data (file uploads), it uses length-prefixed framing (the Content-Length header) for the body.
SMTP (email protocol) ends a message body with the sequence CRLF . CRLF (a line containing only a period). If the message body contains a line starting with a period, the sender must add another period at the start (dot stuffing), and the receiver removes the extra period after receiving.
Delimiter framing works well for text-based protocols where the natural content (human-readable text) is unlikely to contain the delimiter. For binary protocols, length-prefixed framing is cleaner.
Framing in Ethernet
Ethernet’s framing is visible in its frame format. The preamble (7 bytes of alternating 1s and 0s) and start frame delimiter (the byte 10101011) mark the beginning of each frame. The length/EtherType field tells the receiver how many bytes of payload follow, allowing the receiver to determine where the frame ends.
Ethernet also uses the inter-frame gap — a minimum 12-byte silence between frames — to ensure the receiver has time to process one frame before the next begins. This time boundary is a form of framing at the medium level, distinct from the explicit length-based framing within the frame.
Understanding that Ethernet frames have explicit beginnings (SFD), explicit payload lengths, and error detection (CRC) explains why Ethernet can deliver frames reliably even across hubs that retransmit all received signals indiscriminately. The structure built into the frame format allows each receiver to extract correctly framed data from the bit stream.