In this lesson, you will learn how to reconstruct fragmented data packets in a TCP stream by maintaining an internal buffer to hold partial information until a complete frame is formed.
The Problem with TCP
When you read from a TCP socket in Node.js, the data event doesn't guarantee you’ll receive a complete "message." TCP is a stream-oriented protocol, not a message-oriented one. A single large JSON object might arrive in three separate data chunks, or conversely, two distinct messages might arrive bundled inside one single chunk. If you try to parse a partial chunk immediately, your application will crash.
Maintaining State
To handle this, your stream processor must act as a stateful "accumulator." You need a buffer variable outside the scope of the data event handler that persists across chunks.
Here is how you handle it:
let buffer = '';
socket.on('data', (chunk) => {
// 1. Add new chunk to the existing buffer
buffer += chunk.toString();
// 2. Look for a delimiter (like a newline)
let boundary = buffer.indexOf('\n');
// 3. Process all complete frames found in the buffer
while (boundary !== -1) {
const completeMessage = buffer.slice(0, boundary);
processMessage(completeMessage);
// 4. Update the buffer to remove the processed part
buffer = buffer.slice(boundary + 1);
boundary = buffer.indexOf('\n');
}
});
Why This Works
By using a while loop, you safely manage the "leftovers." If a chunk arrives and does not contain a delimiter, buffer.indexOf('\n') returns -1, the loop is skipped, and the data is safely stored in buffer for the next data event. Once the next piece of the frame arrives, the buffer finally contains the full message, the boundary is found, and your logic proceeds. This pattern essentially bridges the gap between raw, unpredictable network chunks and logical, application-ready messages.
Key Takeaway: Never assume a single stream chunk contains a complete message; always buffer incoming data and only process it once your specific delimiter or framing logic confirms a full packet has arrived.