Reliable delivery: Go-Back-N and Selective Repeat

Advanced

Packets get lost, damaged (and thrown away by the checksum) or delayed. To deliver everything anyway, a sender needs three tools:

  • sequence numbers, so the receiver knows what it has and spots duplicates;
  • acknowledgements (ACKs), so the sender knows what arrived;
  • a timeout: no ACK in time means "send it again".

Stop-and-wait is safe but slow

The simplest protocol sends one packet and waits for its ACK. It works, but the link sits idle for a whole round trip after every packet:

packet_bits = 8000              # a 1000-byte packet
rate = 1_000_000_000            # 1 Gbps
rtt = 0.030                     # 30 ms round trip

send_time = packet_bits / rate
busy = send_time / (rtt + send_time)
print("stop-and-wait uses", round(100 * busy, 3), "% of the link")
for window in [10, 100, 1000]:
    print("window", window, "uses", round(min(1, window * busy) * 100, 2), "%")
Open in compiler

On a fast, long link, stop-and-wait uses a tiny fraction of the capacity. The cure is pipelining: keep up to N packets "in flight" before any ACK returns. N is the window, and it slides forward as ACKs arrive.

Go-Back-N

The receiver accepts packets only in order and sends cumulative ACKs: "ACK 5" means "everything up to 5 arrived". An out-of-order packet is thrown away. When the oldest packet times out, the sender goes back and resends it and every packet after it.

Selective Repeat

The receiver keeps out-of-order packets in a buffer and ACKs each one separately. Each packet has its own timer, and only the packets actually lost are sent again. It uses the link better, at the cost of buffer memory and more bookkeeping. Its window must be at most half the range of sequence numbers, or an old duplicate could be mistaken for a new packet.

Choose a protocol, lose a packet or an ACK, and step through:

Lose packet 2 with Go-Back-N and 10 transmissions are needed; with Selective Repeat, 9. Now lose ACK 1 instead: Go-Back-N needs no resend at all, because ACK 2 confirms packet 1 too.

packets, window = 6, 3
lost = {2}                          # packet 2 is lost the first time
base, sent = 0, 0

while base < packets:
    batch = list(range(base, min(base + window, packets)))
    sent += len(batch)
    first_lost = None
    for p in batch:
        if p in lost:
            lost.discard(p)
            if first_lost is None:
                first_lost = p
    print("send", batch, "-> lost:", first_lost)
    base = batch[-1] + 1 if first_lost is None else first_lost
print("transmissions:", sent, "for", packets, "packets")
Open in compiler

TCP mixes the two ideas: cumulative ACKs like Go-Back-N, but receivers keep out-of-order data, and the sender usually resends only the missing segment. Three duplicate ACKs for the same byte trigger a fast retransmit without waiting for the timeout.

Common mistakes

  • Forgetting that ACKs can be lost too: the sender then resends data the receiver already has, and sequence numbers let the receiver throw the duplicate away.
  • Thinking a bigger window is always better: it also has to fit the receiver's buffer (flow control) and the network (congestion control, next lesson).
  • Mixing up the rules: Go-Back-N resends everything from the lost packet on; Selective Repeat resends only what was lost.

Quick check

1. Why is stop-and-wait slow on long, fast links?
2. Go-Back-N, window 4: packets 0 to 3 are sent and 1 is lost. What is resent after the timeout?
3. What does Selective Repeat's receiver do with an out-of-order packet?
4. In Go-Back-N, ACK 1 is lost but ACK 2 arrives. What happens?

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.