How TCP Handles Flow Control, Retransmission, and Congestion
The article explains TCP's retransmission mechanisms (timeout and fast retransmit), selective acknowledgment (SACK), sliding window and MSS limits, packet sticking causes and solutions, as well as flow control and congestion control techniques including slow start, congestion avoidance, and fast recovery.
Retransmission Mechanism
Timeout Retransmission
When a segment is sent, the sender starts a timer. If the ACK is not received before the timer expires, the segment is retransmitted. The timeout interval can be relatively long.
Fast Retransmit
Fast retransmit is data‑driven. After receiving three duplicate ACKs, the sender immediately retransmits the missing segment without waiting for a timeout. The sender must decide whether to retransmit only the lost segment or all subsequent segments. Example: six segments Seq1‑Seq6 are sent, Seq2 and Seq3 are lost, the receiver acknowledges Seq4‑Seq6 with ACK2. The sender can retransmit only Seq2 or retransmit Seq2‑Seq6.
SACK (Selective Acknowledgment)
SACK lets the receiver inform the sender which byte ranges have been received, allowing retransmission of only the missing data. In the illustrated case, three identical ACKs trigger fast retransmit; the SACK option indicates that only the 200‑299 byte range is missing, so only that segment is resent.
Duplicate SACK
Duplicate SACK can be used to tell the sender which data have been received redundantly.
Sliding Window
TCP sends a new segment only after the previous one has been acknowledged. When round‑trip time is large, this reduces efficiency. TCP therefore introduces a sliding window: the window size is the maximum amount of data that can be sent without waiting for an ACK.
The receiver’s advertised window determines the sender’s allowed window size; the sender must not exceed it. Because the receiver’s window changes dynamically as it reads data, the sender’s effective window is approximately equal to the receiver’s.
MSS Limits
Link‑layer MTU limits the maximum packet size (e.g., Ethernet MTU 1500, FDDI MTU 4352, loopback MTU 65535).
MSS (Maximum Segment Size) = MTU − TCP header (20 bytes) − IP header (20 bytes). For Ethernet, MSS = 1500 − 40 = 1460 bytes.
When sending large data, TCP splits it into MSS‑sized segments.
During the three‑way handshake each side advertises its MSS; the smaller value is used.
TCP Packet Sticking (粘包)
Packet sticking occurs because the receiver cannot determine message boundaries. It can be caused by both sender‑side and receiver‑side behaviors.
Sender‑Side Causes
The Nagle algorithm buffers small pieces of data until enough data (or an MSS) is accumulated or a timeout (~200 ms) occurs, reducing the number of packets.
Sending is triggered when any of the following conditions is met:
SO_SNDBUF reaches MSS
FIN flag is present
TCP_NODELAY is set
All previously sent data have been ACKed
Timeout expires
Disabling Nagle (setting TCP_NODELAY) eliminates this sender‑side sticking.
Receiver‑Side Causes
The receiver stores incoming packets in a buffer and the application reads them later. If the read rate is slower than the arrival rate, multiple packets may be concatenated, producing a stick. The receiver cannot resolve sticking itself; the application must handle it.
Solutions
Fixed‑length messages (e.g., each message exactly 64 bytes).
Special delimiter characters (e.g., CR/LF in HTTP).
Custom message format such as TLV (Type‑Length‑Value). HTTP 1.1 uses TLV; HTTP 2.0 uses LTV.
Flow Control
The sender must respect the receiver’s processing capacity. Flow control limits the amount of data sent to the size of the receiver’s advertised sliding window. If the server is busy, it reduces its receive window.
Congestion Control
Congestion control prevents the sender’s data from filling network buffers. When congestion causes packet loss, TCP retransmits, which adds load to the network and can create a vicious cycle.
Congestion control uses the congestion window ( cwnd), a state variable maintained by the sender and adjusted according to network conditions.
Slow Start
During slow start, cwnd increases by one for each received ACK. Starting from cwnd = 1, the number of packets that can be sent grows exponentially until cwnd reaches the slow‑start threshold ( ssthresh).
When cwnd < ssthresh, slow start is used; when cwnd ≥ ssthresh, congestion avoidance takes over.
Congestion Avoidance
For each ACK, cwnd increases by 1/cwnd. Assuming ssthresh = 8, after eight ACKs cwnd grows by one.
Congestion Occurrence
When congestion is detected, two retransmission strategies are possible: timeout retransmission and fast retransmit.
Timeout Retransmission
Set ssthresh = cwnd/2.
Reset cwnd = 1.
Afterwards, slow start restarts with a reduced sending rate.
Fast Retransmit
Upon receiving three duplicate ACKs, the sender retransmits the missing segment immediately.
Set cwnd = cwnd/2.
Set ssthresh = cwnd.
This leads to the fast recovery algorithm.
Fast Recovery
Set cwnd = ssthresh + 3 (the “+3” accounts for the three duplicate ACKs).
Retransmit the lost segment.
If additional duplicate ACKs arrive, increase cwnd by 1; when a new ACK arrives, set cwnd to the stored ssthresh and return to congestion avoidance.
Unlike timeout retransmission, fast recovery keeps cwnd at a relatively high value and grows linearly thereafter.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
