TCP (Transmission Control Protocol) Transmission Control Protocol The Internet transport protocol that delivers data reliably and in order, with flow control and congestion control. introduced in ch. 1 recovers from loss with one timer and a counting trick: three acknowledgements that ask for the same byte mean the segment after it is gone.
Words you will meet
SendBase— the sequence number of the oldest unacknowledged byte.- Duplicate acknowledgement — a second acknowledgement asking again for a byte already asked for.
- Fast retransmit — resending on three duplicates, without waiting for the timer.
- Delayed acknowledgement — waiting up to 500 ms so one acknowledgement can cover two segments.
- SACK — an optional extension that lets a receiver acknowledge out-of-order segments individually.
Why this matters
IP (Internet Protocol) Internet Protocol The network-layer protocol that defines the datagram format and addressing every Internet device must use. introduced in ch. 1 guarantees nothing. TCP (Transmission Control Protocol) Transmission Control Protocol The Internet transport protocol that delivers data reliably and in order, with flow control and congestion control. introduced in ch. 1 guarantees that the byte stream a process reads out of its receive buffer is uncorrupted, without gaps, without duplication, and in sequence — exactly the stream the other side wrote.
This section is how. It is also where section 3.4’s question finally gets answered. TCP has cumulative acknowledgements like Go-Back-N and retransmits one segment at a time like selective repeat, and the book’s verdict is that it is neither.
The sender, in three events
Section 3.4.4 assumed a timer per outstanding packet, which is conceptually easiest. In practice that bookkeeping costs more than it is worth, so RFC (Request For Comments) Request For Comments The name of an IETF standards document. There are currently nearly 9000 of them. introduced in ch. 1 6298 recommends a single retransmission timer, however many segments are outstanding. Everything below follows that recommendation.
SendBase is the sequence number of the oldest unacknowledged byte — so SendBase − 1 is the last byte known to have arrived correctly and in order. NextSeqNum is where the next new segment will start.
Two variables and three events. Everything TCP does for reliability in the simple case is here; fast retransmit adds one branch to the third event.
Read all steps as text
- 0 — Two variables — SendBase is the sequence number of the oldest unacknowledged byte — so SendBase − 1 is the last byte known to have arrived correctly and in order. NextSeqNum is where the next new segment will start.
- 1 — Data received from the application above — Create a segment with sequence number NextSeqNum. If the timer is not already running, start it. Pass the segment to IP. Then advance NextSeqNum by the number of bytes just sent — not by one, because the numbering counts bytes.
- 2 — The timer expires — Retransmit the not-yet-acknowledged segment with the SMALLEST sequence number, and restart the timer. One segment — not the whole outstanding window. That single word is most of the difference from Go-Back-N.
- 3 — An acknowledgement arrives, carrying value y — If y is greater than SendBase, it acknowledges something new: move SendBase up to y, and restart the timer if any segments are still outstanding. If y is not greater, it is a duplicate — and in the simplified sender, nothing happens at all.
In plain words
Two variables and three events, and the whole of simple TCP reliability is in them.
The detail worth pausing on is in event 2: on a timeout, TCP resends the segment with the smallest unacknowledged sequence number. One segment. Go-Back-N would resend every unacknowledged segment, and that single word is where the two protocols part company.
Four scenarios
The data arrived. Only the acknowledgement was lost, so the sender times out and resends something the receiver already has.
Click any arrow to see what that message says and why it is sent.
The same two hosts every time. Switch between them and watch how little the sender has to do to cope with each.
Read this diagram as text
- Host A sends Seq=92, 8 bytes to Host B. Sequence number 92 means this segment’s first byte is byte 92 of the stream. Eight bytes, so it covers 92 through 99.
- Host B sends ACK=100 to Host A — lost. The receiver has bytes 92–99 and now expects byte 100, so it acknowledges with 100 — one past the last byte received. The acknowledgement is lost on the way back.
- Host A sends Seq=92, 8 bytes (resent) to Host B — retransmission. The timer expired. The sender has no idea whether the data or the acknowledgement was lost, and does not need to know.
- Host B sends ACK=100 to Host A. The receiver sees from the sequence number that it already has these bytes, so it discards the data — and acknowledges again, because the sender is clearly still waiting.
Lifelines, left to right: Host A (host), Host B (server).
Scenario b is the one that separates TCP from Go-Back-N
Two segments are outstanding and both arrive perfectly. Both acknowledgements are slow. The timer for segment 92 expires — and TCP resends only segment 92.
Go-Back-N in the same situation would resend segment 92 and segment 100, even though segment 100 arrived intact. TCP does not, and by the time ACK=120 gets through, segment 100 never needs resending at all.
Scenario c makes the same point from the other side: a lost acknowledgement costs nothing as long as a later cumulative one arrives before the timer runs out.
Doubling the timeout
One modification most implementations make, and it is not really about reliability.
Whenever a timeout occurs, TCP retransmits as described. But it then sets the next timeout to twice the previous value, instead of deriving it from EstimatedRTT and DevRTT as section 3.5.3 described. So 0.75 s becomes 1.5 s, and then 3.0 s. The intervals grow exponentially with each successive retransmission of the same segment.
The doubling applies only to repeated timeouts. When the timer is started after either of the other two events, the interval goes back to being computed from the most recent EstimatedRTT and DevRTT.
Why exponential, and why here
Timeout doubling timeout doubling Simple Waiting twice as long after each retransmission of the same segment. Precise On each timeout, TCP retransmits the oldest unacknowledged segment and sets the next timeout to twice the previous value instead of recomputing it from EstimatedRTT and DevRTT. Since timeouts usually mean congestion, retransmitting ever more slowly is a crude but real form of congestion control. The same idea appears at the link layer in Ethernet’s CSMA/CD backoff. introduced in ch. 3 — open in glossary provides a limited form of congestion control, and it is the first congestion control in this chapter.
A timer expiring is most likely caused by congestion: too many packets arriving at one or more router queues along the path, causing drops and long delays. If every source responded by retransmitting persistently, the congestion would get worse. Backing off exponentially is a way of not doing that.
The same idea appears at the link layer in Ethernet’s CSMA/CD (Carrier Sense Multiple Access with Collision Detection) Carrier Sense Multiple Access with Collision Detection CSMA plus listening while you speak: a node that detects a collision aborts immediately rather than finishing a frame nobody can read. Ethernet's protocol. introduced in ch. 6 , in chapter 6. Sections 3.6 and 3.7 take it much further.
Fast retransmit
The trouble with timeout-triggered retransmission is that the timeout period can be long. From section 3.5.3, it is the average round trip plus four deviations, and it doubles on every retry. A sender that waits it out on every loss adds a great deal to the end-to-end delay.
Often the sender can tell much sooner, by noticing duplicate acknowledgements duplicate acknowledgement Simple A second ACK asking again for a byte the sender has already been told about. Precise An acknowledgement that re-acknowledges a segment for which the sender has already had an earlier acknowledgement. The receiver generates one whenever a segment arrives out of order, because TCP has no negative acknowledgement and re-asking is the only way to report a gap. A run of them means the network is still delivering, but something in the middle is missing. introduced in ch. 3 — open in glossary .
| TCP receiver action | |
|---|---|
Cells marked ⓘ have an explanation — click to read it. Sortable columns have a ↕ in the heading.
Read the third row twice. It is the one that makes fast retransmit possible, and it is the receiver’s only way of reporting a gap.
Notice the first row: an in-order segment does not produce an immediate reply at all. That is a delayed acknowledgement delayed acknowledgement Simple Waiting a short while before acknowledging, in the hope of acknowledging two segments at once. Precise The policy in Table 3.2 [RFC 5681]: on the arrival of an in-order segment with everything before it already acknowledged, the receiver waits up to 500 ms for a second in-order segment and then sends one cumulative acknowledgement for both. If nothing arrives in that interval it acknowledges the single segment. introduced in ch. 3 — open in glossary , and it exists so that one acknowledgement can often cover two segments.
When a receiver gets a segment with a sequence number larger than the next expected one, it can see a gap — a missing segment, from loss or from reordering. Since TCP has no negative acknowledgement, it cannot say so directly. So it re-acknowledges the last in-order byte it has, which produces a duplicate.
Because a sender usually has many segments in flight, one loss produces a run of these back to back.
The rule, and the off-by-one hiding in it
Suppose the sender receives three duplicate acknowledgements for the same data. It concludes that the segment following the one being acknowledged has been lost, and performs a fast retransmit fast retransmit Simple Resending a segment as soon as three duplicate ACKs arrive, without waiting for the timer. Precise On receiving three duplicate acknowledgements for the same data — four acknowledgements of that byte in total — the TCP sender concludes that the segment after the acknowledged one is lost and retransmits it immediately, before its timer expires [RFC 5681]. Since a timeout interval can be far longer than a round-trip time, this removes a large part of the delay caused by a single loss. introduced in ch. 3 — open in glossary [RFC 5681], resending that segment before its timer expires.
Count the arrows in scenario d. There are four acknowledgements carrying the value 100:
- the first is the original, generated by segment 92 arriving in order;
- the next three are duplicates, generated by segments 120, 135 and 141 arriving out of order.
So “three duplicate acknowledgements” means four acknowledgements in total. The book says as much later, in section 3.7.1: “one original ACK and then three duplicate ACKs”.
The ACK received event of the simplified sender gains an else branch, and
that branch is the whole of fast retransmit:
event: ACK received, with ACK field value of y
if (y > SendBase) {
SendBase = y
if (there are currently any not yet acknowledged segments)
start timer
}
else { /* a duplicate ACK for an already ACKed segment */
increment number of duplicate ACKs received for y
if (number of duplicate ACKs received for y == 3)
/* TCP fast retransmit */
resend segment with sequence number y
}
break;
Why three, and not one?
A single duplicate acknowledgement is weak evidence. Segments can arrive out of order simply because the network reordered them, which section 3.4.4 warned that a real network does. In that case the missing segment is not lost at all and will turn up shortly.
Retransmitting on the first duplicate would therefore cause a great many unnecessary retransmissions, which is exactly what congestion does not need. Waiting for three is a bet that mild reordering will not produce that many.
The book leaves the question as a homework problem rather than answering it, so this is the reasoning rather than a quotation.
So is TCP Go-Back-N or selective repeat?
| Go-Back-N§3.4.3 | Selective repeat§3.4.4 | TCPthis section | |
|---|---|---|---|
| Acknowledgements | |||
| Sender keeps | |||
| Receiver buffers out of order | |||
| Timers | |||
| On a timeout, resend | |||
| One acknowledgement lost among many | |||
| So which is it? |
Cells marked ⓘ have a reason behind them — click to read it.
Every row is a real comparison from the book. Read the last one only after the others.
In plain words
Look at the row for a lost acknowledgement, because the book’s own example lives there.
Send segments 1 through N. All arrive in order and without error. Now lose only the acknowledgement for segment n, while the other N − 1 acknowledgements arrive before their timeouts.
- Go-Back-N would retransmit segment n and n+1, n+2, … N.
- TCP would retransmit at most one segment, n.
- And TCP would not even retransmit n, if the acknowledgement for n+1 arrived before n’s timer expired.
Selective acknowledgement, and the last of the ambiguity
A proposed modification, the selective acknowledgement selective acknowledgement Simple An optional TCP extension letting the receiver name exactly which blocks it has. Precise SACK [RFC 2018]: an extension allowing a TCP receiver to acknowledge out-of-order segments individually, instead of only cumulatively acknowledging the last in-order byte. Combined with selective retransmission — skipping segments the receiver has already reported — it makes TCP behave much like the generic selective-repeat protocol of §3.4.4. introduced in ch. 3 — open in glossary [RFC 2018], lets a TCP receiver acknowledge out-of-order segments selectively rather than only cumulatively acknowledging the last in-order segment.
Combined with selective retransmission — skipping segments the receiver has already reported having — TCP then looks a great deal like the generic selective repeat of section 3.4.4.
So the honest answer, and the book’s: TCP’s error recovery is best categorised as a hybrid of Go-Back-N and selective repeat. It is not a compromise anyone designed in one sitting; it is what thirty years of experience produced.
Check yourself
Check yourself
0 of 6 answered1.predictIn the fast-retransmit run, how many acknowledgements carrying the value 100 does host A receive before it resends?
Count them in the diagram, then read the rule carefully.
2.Why does a TCP receiver send a duplicate acknowledgement instead of saying "segment 100 is missing"?
3.predictSwitch to the run where a cumulative acknowledgement saves the day. ACK=100 is lost. Why is neither segment retransmitted?
4.How many retransmission timers does a TCP sender use, however many segments are outstanding?
5.After a timeout, TCP sets the next TimeoutInterval to double the previous one rather than recomputing it. Why?
6.Is TCP a Go-Back-N protocol or a selective-repeat protocol?
What to remember
- TCP uses one timer, for the oldest unacknowledged segment. On a timeout it resends only the smallest-numbered unacknowledged segment, never the whole sender window.
- Three duplicate acknowledgements — four in total, counting the original — trigger a fast retransmit before the timer expires. Three rather than one, because mild reordering would otherwise cause needless retransmissions.
- TCP is a hybrid: cumulative acknowledgements like Go-Back-N, one-at-a-time retransmission and real buffering like selective repeat. With SACK it is closer still to selective repeat.