Course contentsShow
← Node.js
Lesson 362 of 1,9804. I/O and File System OperationsFree lesson

Handling Partial Data Frames in Networking

Reconstruct incomplete data frames received over fragmented TCP streams using persistent buffers.

In this lesson, you will learn how to reconstruct incomplete data frames received over fragmented TCP streams by using persistent buffers to track incoming binary fragments.

The TCP Fragmentation Problem

When you communicate over TCP, the network does not guarantee that one write call from a sender results in one data event on your receiver. Because TCP is a streaming protocol, a single logical message (a "frame") might arrive in several chunks, or multiple frames might be mashed together into one buffer. If you try to parse a protocol header before you have received the entire frame, your application will crash or process corrupt data.

Persistent Buffers as Staging Areas

To solve this, you need a "stray" or "persistent" buffer that lives outside the scope of individual data events. Think of this as a workbench where you accumulate fragments until you have enough pieces to form a complete message.

Here is how you manage this state:

  1. Initialize: Create a buffer or an array to store bytes that haven't been processed yet.
  2. Concatenate: Every time a data event fires, append the new chunk to your persistent storage.
  3. Parse and Slice: Check if your storage contains at least one full frame. If it does, slice that frame off, process it, and keep the remaining data in your storage for the next event.
let buffer = Buffer.alloc(0);

socket.on('data', (chunk) => {
  // Concatenate new fragment with existing leftovers
  buffer = Buffer.concat([buffer, chunk]);

  // Process as many full frames as possible
  while (buffer.length >= FRAME_SIZE) {
    const frame = buffer.subarray(0, FRAME_SIZE);
    processFrame(frame);
    
    // Update buffer to hold only the remaining incomplete data
    buffer = Buffer.subarray(FRAME_SIZE);
  }
});

By using buffer.subarray() (which provides a view into the original memory), you keep the remaining, incomplete data ready for the next arrival of bytes. This loop ensures that even if a frame is split across three different network packets, your logic will wait patiently until the final byte arrives before attempting to parse the payload.

Key Takeaway: Always maintain a persistent buffer to accumulate incoming TCP chunks, and only parse data once the cumulative length satisfies your protocol's frame requirements.