TCP Error Recovery and Windowing
Introduction
Welcome to Part 9 of the Network Fundamentals study notes! If you haven’t already, we recommend watching the video first.
In Parts 7 and 8 we looked at how TCP and UDP differ, and how TCP builds and tears down connections. Now we complete the TCP picture by looking at two of its most important features: error recovery and windowing. These are the mechanisms that make TCP reliable and efficient.
Error Detection
Data can be lost or corrupted for many reasons — hardware faults, congestion, interference, and more. The data link layer (e.g. Ethernet) will detect and discard corrupted frames using its FCS trailer. Both TCP and UDP can also detect corruption using a checksum field in their headers.
The key difference is what happens next. UDP detects corruption and discards the data — but that’s it. It makes no attempt to recover. TCP goes further: it manages the retransmission of lost or corrupted data. This is why TCP is called reliable and UDP is called unreliable.
Sequence Numbers and Acknowledgements
To understand how TCP recovers from errors, we first need to understand how sequence numbers and acknowledgements work together.
During the Handshake
Recall from Part 8 that the three-way handshake sets an Initial Sequence Number (ISN). During the handshake itself, sequence numbers increment by one per message — SYN, SYN-ACK, ACK each add one.
During Data Transfer
Once the handshake is complete and data starts flowing, the meaning of the sequence number changes. It no longer counts segments — it now counts bytes. Let’s walk through an example:
- The handshake completes with sequence number 99. The first data segment starts at sequence number 100.
- That segment carries 100 bytes of data, so the next segment will start at sequence number 200.
- When the receiver gets the segment, it sends back an ACK. Rather than just setting the ACK flag, it also sets the acknowledgement number to 200.
This is called forward acknowledgement. The acknowledgement number doesn’t say “I got that” — it says “I got everything up to here, and I’m now expecting byte 200 next.” This distinction is important for error recovery.
Error Recovery
Now imagine something goes wrong. Ten segments of 100 bytes each are sent — but the fourth segment (bytes 400–499) never arrives. The receiver gets segments 1, 2, 3, then 5 through 10. It waits a reasonable amount of time for segment 4, but it never comes.
The receiver can still acknowledge what it has. It sends back an ACK with acknowledgement number 400 — meaning “I have everything up to byte 399, and I’m waiting for byte 400 next.” The sender sees this, understands that byte 400 was never received, and retransmits from that point.
This basic approach retransmits all segments from the point of loss — which isn’t perfectly efficient. A more advanced alternative is Selective Acknowledgement (SACK), which lets the receiver tell the sender exactly which ranges of bytes it has, so only the missing ones need to be resent. The important thing to remember for now is that TCP has error recovery, and UDP does not.
Windowing
Sending one segment at a time and waiting for an ACK before sending the next would be extremely slow. Instead, TCP uses windowing, which allows the sender to transmit multiple segments before needing to wait for an acknowledgement.
The amount of data that can be sent before an acknowledgement is required is called the window size. This value is stored in the TCP header’s window field. Here’s a simple example:
- Window size = 1,000 bytes
- The sender sends a 100-byte segment. Window remaining: 900 bytes.
- It keeps sending 100-byte segments. After 10 segments, the window reaches zero.
- The sender stops and waits for an acknowledgement.
- Once the ACK arrives, the window resets and the sender can continue.
In practice, the receiver sends acknowledgements before the window reaches zero — this keeps data flowing without the sender ever having to stop completely.
The Sliding Window
The window size isn’t fixed. It’s set per-connection during the three-way handshake and can change throughout the life of the connection. This is why it’s often called a sliding window or dynamic window.
When a connection starts, neither side knows how reliable the network path is. So TCP typically starts with a relatively small window — say 8 KB. If data is flowing cleanly with no loss, the window grows: 8 KB → 16 KB → 32 KB → 64 KB (the original TCP maximum). Modern implementations can go higher still.
If data loss starts occurring, the window shrinks. A smaller window means data is acknowledged more frequently, which reduces the amount of data that needs to be retransmitted when something goes wrong.
In an extreme case, a receiver that’s overwhelmed can set the window size to zero. This effectively tells the sender to pause completely, giving the receiver time to catch up. This is a form of flow control — though seeing a zero window is usually a sign of a larger problem somewhere.
Resources
Test your knowledge with the Introduction to Networking quizzes.
