Interview Torture: What Are TCP Sticky/Unsticky Packet Issues and Why They Matter
The article explains that TCP's byte‑stream nature causes sticky and unpacked packet problems, analyzes why they occur, compares UDP, and presents four application‑layer solutions—especially the Header‑Body length‑field approach used by Netty—providing code examples and interview‑ready answers.
Interview Points
TCP fundamentals : interviewers expect you to know TCP is a byte‑stream protocol and understand its impact.
Problem‑solving ability : demonstrate how to design application‑layer protocols (fixed length, delimiter, Header‑Body, custom) to address the issue.
Practical awareness : if you have used Netty or a custom RPC framework, discuss real‑world handling of sticky/unsticky packets.
Core Answer
TCP is a byte‑stream protocol that does not guarantee message boundaries. When the sender transmits multiple packets, the receiver may read them together ( sticky packet ) or a single packet may be split across multiple reads ( unsticky packet ).
Fundamentally, this is not a TCP bug but a design characteristic: TCP only ensures reliable, ordered delivery of bytes and has no notion of where one logical message ends and the next begins.
Deep Analysis
1. Why do sticky and unsticky packets happen?
Because TCP treats data as a continuous stream of bytes. The kernel buffers data on both send and receive sides, and the TCP stack decides how to segment and merge data.
Nagle algorithm : aggregates small packets into a larger one to improve network utilization, leading to sticky packets.
Receiver read delay : if the receiver does not call read() promptly, data accumulates in the buffer and is returned as a larger chunk.
MSS/MTU limits : when data exceeds the maximum segment size, TCP fragments it, causing unsticky packets.
Buffer size : if the buffer supplied to recv() is smaller than the incoming data, the data is split across multiple reads.
Below is a diagram of the TCP data flow, highlighting the buffering stage:
2. Does UDP have this problem?
No. UDP is a datagram‑oriented protocol; each sendto() call corresponds to a complete datagram, and each recvfrom() reads exactly one datagram, preserving natural boundaries.
Mentioning that UDP does not suffer from sticky/unsticky packets can impress interviewers.
3. How to solve sticky/unsticky packets?
The essential idea is to define message boundaries at the application layer so the receiver knows where a complete message starts and ends. Four common approaches are:
Fixed‑length messages : each message has a predetermined size; shorter messages are padded. Pros: simple implementation. Cons: bandwidth waste, low flexibility.
Special delimiters : use characters such as \n or \r\n to separate messages. Pros: straightforward. Cons: message body cannot contain the delimiter.
Header‑Body (length field) : send a length field first, then the body. Pros: most generic and flexible. Cons: slightly more complex to implement.
Custom protocol : combine magic numbers, version, length, and payload for full control. Pros: most complete. Cons: highest complexity.
The industry‑standard solution is the Header‑Body length‑field method, which Netty and most RPC frameworks adopt.
4. Header‑Body solution details
A typical message format includes:
Magic Number : identifies the protocol (e.g., 0xaced for Java serialization).
Length Field : records the byte length of the body; the receiver reads the fixed‑size header, extracts the length, then reads exactly that many bytes.
Body : the actual business data, which can be JSON, Protobuf, etc.
Decoding logic (pseudocode):
// Pseudocode: receiver decoding flow
while (true) {
// 1. Ensure at least a full header (e.g., 8 bytes: 4‑byte magic + 4‑byte length)
if (readableBytes() < 8) { return; }
markReaderIndex();
int magic = readInt();
if (magic != 0xCAFE) { throw new Exception("Illegal packet"); }
int length = readInt();
if (readableBytes() < length) { resetReaderIndex(); return; }
byte[] body = readBytes(length);
handleMsg(body);
}5. Netty built‑in decoders
FixedLengthFrameDecoder – for fixed‑length messages.
DelimiterBasedFrameDecoder – for special character delimiters.
LengthFieldBasedFrameDecoder – implements the Header‑Body length‑field scheme.
LineBasedFrameDecoder – for line delimiters ( \n or \r\n).
The most commonly used decoder is LengthFieldBasedFrameDecoder. A typical configuration:
// Parameter explanation:
// maxFrameLength = 1024 → maximum frame size
// lengthFieldOffset = 0 → length field starts at byte 0
// lengthFieldLength = 4 → length field occupies 4 bytes
// lengthAdjustment = 0 → length value equals body length
// initialBytesToStrip = 0 → do not strip header after decoding
ch.pipeline().addLast(
new LengthFieldBasedFrameDecoder(1024, 0, 4, 0, 0)
);Understanding these parameters may seem tricky at first, but once the principle is clear, they are just formulaic settings. Explaining them confidently shows practical Netty experience.
High‑frequency follow‑up questions
Why is TCP byte‑stream oriented instead of message oriented? Because TCP aims to provide reliable, ordered byte delivery, allowing upper‑layer protocols to define their own message formats for maximum flexibility.
If the receiver reads slowly while the sender floods data, what happens? The receive buffer fills, worsening sticky packets. When the buffer is full, TCP’s flow‑control (sliding window) signals the sender to slow down; extreme cases may trigger OOM.
How does HTTP solve the sticky packet problem? HTTP/1.1 uses the Content‑Length header or Transfer‑Encoding: chunked to indicate body length. HTTP/2 uses a binary frame format with explicit length fields. All are application‑layer boundary definitions.
Common interview variants
"How does Netty solve sticky/unsticky packets?"
"Why does TCP have sticky packets while UDP does not?"
"Design a custom communication protocol to avoid sticky packets."
"What are the parameters of LengthFieldBasedFrameDecoder and what do they mean?"
Memory Mnemonics
Sticky/Unsticky root cause : byte stream, no boundaries (TCP only transports bytes, not messages).
Solution idea : define boundaries at the application layer (fixed length, delimiter, length field, custom protocol).
Mainstream solution : send length first then body (Header‑Body), implemented in Netty by LengthFieldBasedFrameDecoder.
Summary
TCP sticky/unsticky packets are an inevitable result of TCP’s byte‑stream design, not a bug. The proper remedy is to define message boundaries in the application layer, with the Header‑Body length‑field method being the industry‑standard approach. Netty provides LengthFieldBasedFrameDecoder for out‑of‑the‑box handling. Clearly explaining both the cause and the solution will greatly impress interviewers.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Handbook
Focused on Java interview questions and practical article sharing, covering algorithms, databases, Spring Boot, microservices, high concurrency, JVM, Docker containers, and ELK-related knowledge. Looking forward to progressing together with you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
