4.3.21 · D4Computer Networks

Exercises — TCP flow control — sliding window, receive buffer

2,321 words11 min readBack to topic

Before we start, let me re-anchor the four counters, because every answer below is arithmetic on them. Picture a long tape of numbered bytes.

Figure — TCP flow control — sliding window, receive buffer

Level 1 — Recognition

L1.1RcvBuffer = 8000 bytes. LastByteRcvd = 52000, LastByteRead = 50000. What is the buffer occupancy, and what rwnd does the receiver advertise?

Recall Solution

WHAT we compute: occupancy = the two-pointer gap in the buffer. WHY: those 2000 bytes arrived but the app hasn't read() them yet — they occupy memory. Then the advertised free room: The receiver puts 6000 into the 16-bit Window field.

L1.2 — In which field of which segment does rwnd travel, and who sets it — the sender or the receiver?

Recall Solution

It travels in the 16-bit Window field of the TCP header, and it is written by the receiver (the side whose buffer is being protected). The sender only reads it. See TCP segment header format.


Level 2 — Application

L2.1RcvBuffer = 4000. LastByteRcvd = 30000, LastByteRead = 28800. Sender state: LastByteSent = 30000, LastByteAcked = 29200. How many more bytes may the sender transmit right now?

Recall Solution

Step 1 — advertised room: Step 2 — bytes already in flight (sent, not yet acked): Step 3 — remaining budget = free room minus what's already claiming seats: WHY subtract in-flight: those 800 bytes are travelling toward the buffer and will occupy part of the 2800. Ignoring them would overbook the buffer.

L2.2 — Same connection an instant later: an ACK arrives raising LastByteAcked to 30000, and the app reads nothing new (buffer unchanged, rwnd still 2800). Now how many bytes may the sender push?

Recall Solution

New in-flight: Budget: WHAT just happened geometrically: the ACK slid the window's left edge right up to LastByteSent, freeing the whole advertised window. This is the sliding in sliding window.


Level 3 — Analysis

L3.1 — A receiver advertises rwnd = 0 because its app stopped reading. Later the app reads 3000 bytes, and there is no data for the receiver to send back. Explain the deadlock, and compute what the sender learns and when it learns it under the standard fix.

Recall Solution

The deadlock: with rwnd = 0 the sender is frozen (LastByteSent − LastByteAcked ≤ 0, nothing new allowed). When the app reads 3000 bytes, the receiver's occupancy drops and it would advertise a bigger window — but a receiver emits segments only when it has data or an ACK to send. With no traffic, that fresh window update may never be transmitted, so the sender waits forever. The fix — Zero-Window Probe: the sender periodically sends a 1-byte probe segment. The receiver must reply (it now has something to ACK), and that reply carries the current window. If it read 3000 bytes and, say, RcvBuffer = 4000 with occupancy now 1000, the probe response advertises: The sender learns "3000 bytes of room" on the next probe reply, and resumes.

L3.2 — Explain why flow control (rwnd) and congestion control (cwnd) can give different limits, and state the single rule the sender actually applies. If rwnd = 12000 and cwnd = 5000, what is the sender's true window?

Recall Solution

rwnd is set by the receiver to protect its buffer (an endpoint memory limit). cwnd is estimated by the sender from loss and RTT to protect the network path (see TCP congestion control — cwnd, AIMD). They measure two independent bottlenecks, so they need not agree. The sender obeys both by taking the smaller: Here the network is the bottleneck, not the receiver's buffer.


Level 4 — Synthesis

L4.1 — A link has bandwidth B = 1 \text{ Gbit/s} = 10^9 bits/s and round-trip time RTT = 40 \text{ ms}. Compute the Bandwidth-delay product in bytes. Then explain why the plain 16-bit Window field cannot keep this pipe full, and give the smallest window-scale shift s that lets the receiver advertise at least the BDP.

Recall Solution

Step 1 — BDP in bits, then bytes. BDP is "how many bits fit in the pipe at once" = bandwidth × RTT: WHY BDP: to keep the sender continuously busy, the window must cover a full round trip's worth of unacked data. If the window is smaller, the sender stalls waiting for ACKs. Step 2 — the 16-bit ceiling. A raw Window field maxes at bytes ≈ 64 KB, which is ~76× too small for 5 MB. So the pipe would sit mostly empty — exactly the failure of a too-short window. Step 3 — window scale. Effective window , and Window . We need: Since , the smallest shift is: With s = 7, one Window unit = 128 bytes, so max advertisable bytes > 5 MB. ✔

L4.2 — Continuing L4.1 with s = 7: the receiver wants to advertise exactly 5,000,000 bytes of free room. What Window field value should it write (round down to a value it can actually represent), and what does that actually advertise?

Recall Solution

The wire value must be an integer, and effective = value × 128. To not over-promise, round down: Actual advertised room: WHY round down: rounding up would advertise more room than exists → risk of buffer overflow. The lost 64 bytes of granularity are harmless.


Level 5 — Mastery

L5.1 — Full picture. A connection uses window scale s = 4 on both the raw wire Window values below. Given at one instant:

  • RcvBuffer = 65536, LastByteRcvd = 200000, LastByteRead = 190000 (receiver side)
  • LastByteSent = 205000, LastByteAcked = 198000 (sender side)
  • the sender's congestion window cwnd = 6000 bytes

(a) What effective rwnd does the receiver advertise? (b) What raw Window value goes on the wire? (c) How many bytes is the sender in-flight? (d) What is the sender's true allowed extra bytes right now?

Recall Solution

(a) rwnd. Occupancy = . (b) raw Window value. With s = 4, effective = value × = value × 16. Round down: So the wire carries 3471, meaning 55536 bytes exactly. (c) in-flight. (d) true budget. First the flow-control budget: But the sender also obeys congestion control; the allowed window is min(rwnd, cwnd) = min(55536, 6000) = 6000, and its own budget: A negative result means the sender is already 1000 bytes over its congestion limit — it must send 0 more bytes and wait for ACKs to slide the window forward. The network, not the receiver, is the binding constraint here.

L5.2 — Design reasoning. The receiver in L5.1 momentarily has its app stop reading; occupancy climbs to RcvBuffer. Trace what the sender sees, what it does, and how the connection recovers — naming every mechanism.

Recall Solution
  1. Occupancy → 65536 = RcvBuffer, so . Receiver advertises Window = 0.
  2. Sender now has : frozen, may send nothing.
  3. To avoid the zero-window deadlock, the sender starts a persist timer and emits 1-byte zero-window probes.
  4. When the app finally read()s, occupancy drops, rwnd becomes positive; the next probe reply carries the new non-zero Window (scaled by ).
  5. Sender resumes, bounded again by min(rwnd, cwnd). Every brake in play: rwnd (receiver buffer), cwnd (network), zero-window probe (deadlock breaker), window scale (large-window encoding).

Recall One-line self-test before you leave

Cover the answers: rwnd formula? budget formula? which window does the sender obey? what breaks a zero-window deadlock? how does scaling encode a big window? rwnd = RcvBuffer − occupancy ::: budget = min(rwnd,cwnd) − in-flight ::: min(rwnd,cwnd) ::: zero-window probe ::: effective = Window × 2^s.


Connections