SubnetLayer

Sliding Window & Flow Control

How a receiver throttles a sender — down to a dead stop

Step 1 of 2 — understand the idea. Read this first and the packet trace will confirm what you already expect, instead of teaching you two things at once.

What you'll be able to do

Before this lesson — it builds directly on:
A fast server can produce data far quicker than a slow client can consume it — a phone on a weak CPU, an application busy doing something else. Arriving data has to wait in memory until the application reads it, and that memory is finite. Without a brake, the receiver would simply run out of room and start throwing away data it had already successfully received, which is the most wasteful possible failure. Flow control lets the receiver say 'slow down' before that happens.

✗ Common misunderstanding: The window field advertises how fast the link is.

Why that's wrong: It advertises free space in the receiver's buffer, in bytes. It says nothing about the network between the two hosts.

Correct model: Window = free memory at the receiver. Speed is a consequence (window ÷ round-trip time), not the meaning.

The packets prove it: In the sliding-window trace the window falls to 0 while the link is completely idle — the receiver's application simply stopped reading.

✗ Common misunderstanding: Flow control and congestion control are two names for the same thing.

Why that's wrong: They protect different victims with different mechanisms. Flow control protects the RECEIVER's buffer using the advertised window; congestion control protects the NETWORK using the sender's private cwnd.

Correct model: Two independent brakes, always both active. The sender may have min(rwnd, cwnd) bytes in flight.

The packets prove it: In the rwnd-limited scenario cwnd is large but the 4 KB advertised window is the binding limit; in the congestion-collapse scenario the window is huge and the network is the problem.

Watch these fields in the lab: tcp.windowSize

Receive buffer
Memory at the receiver holding arrived data until the application reads it. Fixed size (here 4000 bytes).
Receive window (rwnd)glossary
The FREE space left in that buffer, advertised in every packet. Shrinks as data waits unread; grows when the app reads.
Bytes in flight
Data the sender has transmitted but not yet had acknowledged. This is the quantity the window limits.
Zero windowglossary
An advertisement of 0: 'stop completely'. Legal, common, and not an error.
Window updateglossary
A packet whose only purpose is announcing that space has freed up.
Buffers, the window, and bytes in flightThe sender holds data in a send buffer. Data that has been sent but not yet acknowledged is in flight. The receiver holds arrived data in a receive buffer until the application reads it, and advertises the remaining free space as the receive window.Sendersend buffer (queued to send)In flightsent, not yet acknowledgedReceiverarrived,unreadfreespaceadvertised window = free spaceRule: bytes in flight must never exceed the advertised window.App reads slowly → unread grows → window shrinks → sender must slow down.Window reaches 0 → sender stops completely until an update arrives.
The advertised window is FREE SPACE in the receiver's buffer — not bandwidth, not speed. It shrinks as data waits unread and reopens when the application reads.

Watch these fields in the lab: tcp.windowSize · tcp.ackNumber

✓ Concept check — before you open the packets

These test the idea, not the trace. You should be able to answer them from the explanation above.

A receiver advertises a window of 0. What does that mean about the network between the two hosts?

Which endpoint decides the value of the receive window, and which one must obey it?

Now that you understand the concept, observe how it appears in the packet exchange.

The lab runs a real simulated capture — pause, step, click any packet, and inspect every byte.