See It Flow
Interactive guide · 8 chapters · ~20 min read

TCP Fundamentals

How two computers that have never spoken before establish a reliable, ordered, congestion-aware byte stream over an unreliable, packet-switched network.

Mangesh MandlikLast updated:
01 · Foundations

What is TCP?

TCP (Transmission Control Protocol) is a connection-oriented transport protocol that uses acknowledgements, sequencing, and retransmission to provide a reliable, ordered, error-checked byte stream to the receiving TCP stack while the connection remains established.

The network layer beneath TCP (IP) makes no promises: packets can be dropped, duplicated, delayed, or delivered out of order. TCP hides most of that from the application while the connection stays healthy, presenting a reliable, ordered stream of bytes instead of raw best-effort packets. If the connection resets or retries are exhausted, TCP cannot deliver data that never made it across.

ClientServerSYNSYN-ACKACK
TCP establishes state on both ends before any data flows — this is what 'connection-oriented' means in practice.

The defining characteristics

Connection-oriented

Before any data is sent, both sides perform a handshake that establishes shared state — sequence numbers, window sizes, and options — for the lifetime of the connection.

Reliable

Sent bytes are acknowledged cumulatively. Missing data is inferred from gaps, duplicate ACKs, or timeout, then retransmitted while the connection remains open.

Ordered

Sequence numbers let the receiver reorder segments that arrive out of order, and the application always sees bytes in the order they were sent.

Congestion-aware

TCP actively monitors the network path and throttles its own sending rate to avoid overwhelming routers and links between the two hosts.

Interactive

Visual Learning

Watch one TCP connection go from handshake to data transfer, loss recovery, flow and congestion control, and graceful teardown — as a single continuous story, not twelve separate explanations.

02 · History & Motivation

Why TCP Exists

IP alone gives you a best-effort datagram service — nothing more. TCP was designed to build reliability on top of a network with none.

Early packet-switched networks (like ARPANET) proved that breaking data into independently routed packets was far more resilient and efficient than dedicated circuits — but it came at a cost: packets could take different routes, arrive out of order, be duplicated, or simply vanish during congestion. Applications like file transfer and remote login needed a transport that could recover from those failures and present an in-order byte stream while the connection survived.

Vint Cerf and Bob Kahn's original 1974 TCP/IP design bundled addressing and reliability into one protocol; it was later split into IP (addressing/routing) and TCP (reliability, flow control, and congestion control) so that low-overhead protocols like UDP could also exist on top of IP for cases where latency, message boundaries, or application-specific recovery mattered more than TCP's built-in retransmission policy.

03 · Comparison

TCP vs UDP

Both sit at the transport layer and both run on top of IP — but they make different trade-offs around reliability, latency, overhead, and who controls recovery behavior.

TCP

Connection-oriented, reliable, ordered, congestion-controlled. Higher overhead (handshake, ACKs, retransmissions) but usually the right choice when the application needs an in-order byte stream and is willing to pay latency to recover from loss while the connection stays up.

UDP

Connectionless, message-oriented datagrams with minimal transport-layer state and no built-in retransmission or ordering. Used for DNS, live video/voice, gaming, and protocols like QUIC where the application wants to choose its own timing and recovery behavior.

04 · Wire format

The TCP Header

Every TCP segment carries a fixed-format header describing sequence state, flags, and window size — this is the mechanism everything else in this module is built on.

Source / destination port

Identify which application on each host the segment belongs to — together with the IP addresses, this forms the 4-tuple that uniquely identifies a connection.

Sequence number

The byte-offset of the first byte in this segment's payload, relative to the connection's initial sequence number (ISN).

Acknowledgement number

The next byte the sender of this segment expects to receive — i.e. "I've successfully received everything before this."

Flags (SYN, ACK, FIN, RST, PSH, URG)

Control bits describing the segment's purpose: SYN opens a connection, FIN closes one, RST aborts one, ACK carries an acknowledgement, PSH asks the receiver to push data to the application immediately.

Window size

How many bytes the sender of this segment is currently willing to receive — the basis of flow control.

05 · Connection setup

The Three-Way Handshake

Before any data flows, both sides must exchange and acknowledge initial sequence numbers — this takes exactly three messages, no fewer.

ClientServerSYNSYN-ACKACK
SYN → SYN-ACK → ACK — each message both proposes a sequence number and acknowledges the peer's.

SYN

The client picks a random initial sequence number (ISN) and sends it in a SYN segment, moving to the SYN_SENT state.

SYN-ACK

The server replies with a SYN-ACK: it acknowledges the client's SYN by setting ACK to the client's ISN + 1, and it contributes its own ISN before moving to SYN_RCVD.

ACK

The client sends a final ACK acknowledging the server's SYN (ACK = server ISN + 1). Both sides are now ESTABLISHED and can exchange data.

06 · Reliability mechanics

Sequence Numbers & Acknowledgements

Every byte in a TCP stream has an implicit position number — this single idea is what makes reordering, duplicate detection, and retransmission possible.

Sequence numbers

Assigned per byte, not per segment — a segment's sequence number is the offset of its first byte. This lets the receiver detect gaps and reassemble out-of-order segments.

Cumulative ACKs

An ACK for byte N means "I have received everything up to but not including N" — a single ACK can acknowledge multiple segments at once.

Worked trace: handshake plus two data segments (illustrative values)

textIllustrative trace — ISNs are normally random 32-bit values; small ones are used here for readability
1  C→S  SYN       seq=1000              win=64240
2  S→C  SYN-ACK   seq=5000  ack=1001     win=65160   (SYN consumes one sequence number)
3  C→S  ACK       seq=1001  ack=5001     win=64240   → both sides ESTABLISHED
4  C→S  ACK,PSH   seq=1001  len=460      (carries bytes 1001–1460)
5  S→C  ACK       seq=5001  ack=1461     win=65160   ("next byte I expect is 1461")
6  S→C  ACK,PSH   seq=5001  len=1000     (carries bytes 5001–6000)
7  C→S  ACK       seq=1461  ack=6001

Read it as bookkeeping: the SYN and SYN-ACK each burn one sequence number, so the first data byte in each direction is ISN + 1. After line 4 the receiver's cumulative ACK is 1461 = 1001 + 460 (the next byte it expects). If line 5 were lost, the ACK in a later segment (for example ack=1461 or higher) would implicitly confirm the same bytes. The win value in each segment is that sender's advertised receive window in bytes (flow control).

07 · Throughput & backpressure

Sliding Window, Flow Control & Congestion Control

Three related-but-distinct mechanisms govern how much data can be in flight at once — and they're commonly confused.

ClientServerwindow = 3 segments in flightcumulative ACK
Multiple segments can be outstanding at once — the window slides forward as ACKs arrive.

Sliding window

Instead of stop-and-wait (one segment per round trip), TCP allows multiple unacknowledged segments in flight, dramatically improving throughput on high-latency links.

Flow control

Protects the RECEIVER — the receiver advertises how much buffer space it has (rwnd), and the sender must never have more unacknowledged data in flight than that.

Congestion control

Protects the NETWORK — the sender maintains its own congestion window (cwnd), grown via Slow Start and Congestion Avoidance, and shrunk sharply when loss is detected.

cwnd over timeloss!
cwnd grows exponentially during slow start, then linearly during congestion avoidance, and drops sharply on loss.
08 · Teardown

Connection Termination

Closing a TCP connection is asymmetric — each direction is closed independently, which is why it typically takes four messages instead of two (the passive side may combine its ACK and FIN into one segment).

ClientServerFINACKFINACK
FIN → ACK → FIN → ACK — each side says goodbye on its own schedule.

Half-close

When one side sends a FIN, it means "I have no more data to send" — but the connection can still receive data in the other direction until that side also sends its FIN.

TIME_WAIT

After sending the final ACK, the active closer waits (typically 2×MSL) before fully releasing the connection — protecting against delayed duplicate segments from an earlier connection that used the same 4-tuple.

Key takeaways
  • TCP builds a reliable, ordered byte stream on top of IP's unreliable, best-effort datagram delivery.
  • The three-way handshake (SYN, SYN-ACK, ACK) proves bidirectional connectivity before any data is exchanged.
  • Sequence numbers and cumulative ACKs are the foundation of both reliability and in-order delivery.
  • Sliding window improves throughput; flow control protects the receiver; congestion control protects the network — three distinct mechanisms.
  • Closing a connection is asymmetric — four messages (FIN/ACK/FIN/ACK) and a TIME_WAIT period, not a simple handshake in reverse.