Comprehensive Study Notes on TCP Operations, Flow and Congestion Control, and Naming Abstractions
Overview of TCP/IP Architecture and State Mechanics
Transmission Control Protocol (TCP) operates as an hourglass protocol within the Internet protocol suite, occupying the central transport layer position connecting user-level applications to underlying network infrastructure. Built around a strict client-server model, TCP establishes stateful connection sessions between communicating hosts. The host initiating communication acts as the client, while the responding entity acts as the server.
TCP manages data stream ordering and reliability using two fundamental header fields: sequence numbers () and acknowledgment numbers (). The sequence number represents the byte stream index of the very first data byte contained within a given segment. The acknowledgment number transmitted back from a receiver indicates the next expected byte index that the receiver expects to receive, explicitly implying that all preceding bytes have been successfully received and assembled.
Unlike theoretical sliding window protocols such as Go-Back-N or Selective Repeat, TCP is a practical protocol refined through extensive empirical research, real-world network deployment, and performance experimentation. Rather than relying solely on pure mathematical models, TCP incorporates heuristic optimizations and practical rules of thumb designed to maintain high throughput and low network overhead across global infrastructure.
TCP Sender-Side Operations and Retransmission Timers
When an application layer process transfers data to the transport layer via a Socket API call (such as a write operation to a socket), the local TCP sender encapsulated the payload into a TCP segment. This segment includes the sequence number representing the next byte position in the outgoing byte stream, alongside the payload length.
Timer management in TCP is engineered to minimize system overhead and maximize throughput. Maintaining numerous running timers introduces processing costs that reduce overall data transfer rates. TCP enforces a single retransmission timer per connection rather than allocating individual timers for every outstanding, unacknowledged segment.
When data arrives from the application via the socket API, TCP creates a segment with equal to the index of the first data byte in the segment. TCP then checks if the single retransmission timer is running. If the timer is not currently running, TCP starts it. The timeout interval serves as an absolute backstop against unrecoverable loss.
If a timeout event occurs, TCP retransmits only the oldest unacknowledged segment—the specific segment that originally triggered the timer. Unlike Go-Back-N, TCP does not retransmit every unacknowledged segment in the pipeline. After retransmitting the oldest segment, TCP restarts the single timer.
When an ACK is received that acknowledges previously unacknowledged data bytes, TCP updates its record of acknowledged bytes. If all outstanding transmitted segments are now acknowledged, the timer is stopped. If unacknowledged segments still remain in flight, TCP restarts the retransmission timer so that the timeout interval measures from the present moment. While a retransmission timer timeout causes recovery delays, TCP mitigates reliance on timers through heuristic mechanisms such as triple duplicate acknowledgments () and Fast Retransmit.
TCP Receiver-Side Operations and Acknowledgement Strategies
The TCP receiver operates as an event-driven system, reacting to segment arrivals and generating acknowledgment signals to optimize network bandwidth efficiency. The receiver balances immediate feedback with cumulative acknowledgment strategies to minimize duplicate header overhead.
When an in-order segment arrives with the exact expected sequence number, and all prior data has already been acknowledged with no pending delayed ACKs, the receiver delays sending an ACK. Delaying the acknowledgment allows the receiver to wait up to for a subsequent in-order data segment or an outgoing application payload to piggyback upon. If a second in-order segment arrives within , the receiver immediately transmits a single cumulative ACK acknowledging both segments, effectively halving acknowledgment packet frequency. If no subsequent segment arrives before the timer expires, a single ACK is generated and transmitted.
When an in-order segment arrives and a delayed ACK is already pending from a previous segment, the receiver immediately generates and transmits a single cumulative ACK encompassing both segments.
When an out-of-order segment arrives with a sequence number higher than the expected sequence number, a gap in the byte stream is detected. The receiver immediately constructs and sends a duplicate ACK. This duplicate ACK explicitly repeats the sequence number of the next expected byte, rather than the sequence number of the out-of-order segment just received. This duplicate ACK stream signals gap detection to the sender, triggering Fast Retransmit.
When a segment arrives that completely or partially fills a gap in received sequence numbers, the receiver immediately transmits an ACK acknowledging the highest contiguous byte received, provided the lower boundary of the gap was filled. Although standard TCP protocol specifications leave out-of-order buffering to implementation discretion, modern TCP stacks universally buffer out-of-order data to prevent unnecessary link retransmissions.
Flow Control Mechanics and Window Management
Flow control prevents a high-speed sender from overwhelming the processing buffer of a slower receiver. TCP enforces end-to-end flow control by matching sender transmission rates directly to the receiver's available application buffer space.
The TCP header contains a dedicated field designated as Window Size (). In every segment sent between endpoints—alongside control flags such as ACK, PSH, SYN, and FIN—the receiving host dynamically communicates its remaining free buffer space. Because TCP connections are full-duplex, both endpoints continually advertise their respective values.
The sender maintains a strict invariant where the total volume of transmitted, unacknowledged data in flight must never exceed the most recently advertised value:
Consider an operational example where a receiver allocates a total buffer capacity of (). The sender writes () of data starting at sequence number . Upon receiving this segment, the receiver stores the in its buffer and transmits an ACK with and an advertised window size of ( remaining).
If the sender application subsequently attempts to write () of data to the socket, the transport layer inspects the advertised of . To prevent buffer overflow, the sender transmits only the first () and retains the remaining () in its local queue. Upon receiving this , the receiver's buffer is completely filled, prompting the receiver to transmit an ACK requesting byte index with an advertised window of .
Transmission halts until the receiving application reads data from the buffer. Once the application reads () from the buffer, the transport layer generates an explicit window update ACK signaling . These specific window update ACKs are excluded from the threshold used to trigger Fast Retransmit. Upon receipt of this update, the sender transmits the remaining queued () payload.
Network Congestion Control and Capacity Probing
While flow control manages receiver buffer capacity, congestion control manages the capacity of intermediate network infrastructure such as routers and switches. Congestion occurs when excessive network sources attempt to transmit data through intermediate links faster than router buffers can process and forward them.
Symptoms of congestion include large router queue accumulations, increased end-to-end latency (jitter), and packet loss due to router queue overflows. Aggressively retransmitting lost packets into a congested network creates a severe negative feedback cycle, exacerbating congestion and increasing packet loss rates.
TCP uses dropped packets as a primary proxy measurement for network congestion. Because physical bit error rates on modern links are extremely low, packet loss almost exclusively signifies router buffer overflow along the network path. Dropping a packet mid-route wastes all upstream link bandwidth used to convey the packet and underutilizes downstream links.
To discover available path capacity without causing immediate congestion, TCP employs the Slow Start algorithm. Slow Start dynamically probes connection capacity by monitoring the Round Trip Time ()—the duration required for a segment to travel to the receiver and for its corresponding ACK to return. TCP tracks using a weighted moving average across active connections.
During initial connection setup, TCP sets its Congestion Window () to an initial small size (e.g., maximum segment size). For every during Slow Start, doubles exponentially ( segments) as long as ACKs return successfully.
Exponential growth continues until packet loss is detected or reaches a parameter known as the Slow Start Threshold (). represents an estimate of safe link capacity based on historical performance. Once , TCP transitions from exponential growth to linear growth (Additive Increase), incrementing by segment per
Different TCP implementations handle packet loss recovery through distinct congestion avoidance algorithms:
In TCP Tahoe, when loss is detected via a timeout or , the protocol sets and resets . It then re-enters Slow Start up to the new , after which it resumes linear growth.
In TCP Reno, when loss is detected via , the protocol sets and sets (Fast Recovery), bypassing the reset back to segment and continuing with linear growth. TCP Reno was designed for modern, high-quality transmission media such as fiber optics with lower structural noise rates.
Bandwidth Allocation Fairness in TCP and UDP
A key property of TCP congestion control is fair link capacity allocation. If independent TCP sessions pass through a shared bottleneck link of total bandwidth , each connection dynamically converges toward an equal bandwidth allocation of . The additive-increase multiplicative-decrease (AIMD) probing process naturally forces over-allocating flows to throttle back while under-allocating flows expand, maintaining convergence around the equal share point. TCP Tahoe achieves fair link sharing faster than TCP Reno because Tahoe resets its window to the initial size upon loss detection.
However, system-wide fairness is degraded by protocol differences and application behavior:
User Datagram Protocol (UDP) flows do not incorporate congestion control mechanisms. UDP applications transmit packets at fixed or unregulated rates regardless of network drop rates. When TCP flows compete with UDP streams across a congested bottleneck, TCP continually throttles its window back while UDP continues uninhibited, causing TCP to lose its fair link share. Modern routers employ aggressive firewalls and selective packet dropping to mitigate unregulated UDP throughput.
Applications can circumvent TCP fairness by opening multiple concurrent TCP connections. In HTTP/1.0, web browsers routinely established separate parallel TCP connections for every embedded resource in an HTML document.
Suppose a bottleneck link currently supports active TCP connections, each receiving a fair share of of total bandwidth. If a new application requests a single TCP connection, total active connections rise to , and each connection adjusts to a fair share of . However, if the new application opens parallel TCP connections simultaneously, the total connection count becomes . The single application secures of total bottleneck bandwidth, leaving the remaining original connections to split .
Application Layer Naming, Domain Name System, and Resource Identifiers
While transport protocols (TCP and UDP) rely strictly on IP addresses and port numbers, human usability and operational scalability require higher-level abstraction provided by the application layer. IP addresses identify specific physical or virtual network interfaces, not abstract services or applications.
Domain names decouple service identity from underlying physical host network addresses, providing location independence and support for server replication:
A Name is a persistent, unique identifier representing an entity's identity (e.g., Pizza Palace). It remains constant even if location changes.
An Address defines the current network or physical location of a host (e.g., 12 Murphy Street moving to 6 Happy Avenue, or an IP address). Addresses are dynamic and subject to operational re-assignment.
A Service represents functional capability provided by application software running on servers (e.g., web hosting, firewalls, virtual private networks). Multiple physical servers with distinct IP addresses can serve a single service name to distribute operational load.
At the application layer, resources are located using Uniform Resource Locators (URLs). A URL consists of three primary components:
Protocol Identifier: Specifies the application layer protocol (e.g.,
https), which is transported across the network via underlying transport protocols like TCP.Host Name / Domain Name: Identifies the target domain (e.g.,
ecs.wgtn.ac.nz), which is resolved to an IP address via the Domain Name System (DNS).Host-Specific String / Relative Path: Defines the resource path on the destination host (e.g.,
/courses/nwin243_200362/), directing the destination server application to the specific requested file or resource.
Because transport headers contain no fields for domain names or relative paths, client applications resolve host names to IP addresses prior to initiating TCP connection handshakes.