100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is the TCP State Machine?

Understand the TCP state machine — LISTEN, SYN_SENT, ESTABLISHED, FIN_WAIT, TIME_WAIT — and how connections open and close.

hardQ182 of 224 in Computer Networks Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

The TCP state machine is the finite set of connection states, such as CLOSED, LISTEN, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT_1/2, CLOSE_WAIT, LAST_ACK, CLOSING, and TIME_WAIT, that a TCP socket moves through in a defined order as it opens, transfers data, and closes, with transitions triggered by sent/received segments like SYN, ACK, and FIN.

A passive endpoint (a server) starts in LISTEN, waiting for a SYN, while an active endpoint (a client) moves from CLOSED to SYN_SENT after sending its own SYN; once the three-way handshake completes, both sides reach ESTABLISHED and can exchange data. Closing follows a separate path: the side that calls close() first sends a FIN and moves to FIN_WAIT_1, then FIN_WAIT_2 once its FIN is acknowledged, while the peer moves to CLOSE_WAIT on receiving that FIN and later to LAST_ACK after it sends its own FIN. The side that initiated the close ends up in TIME_WAIT for a defined interval (commonly twice the maximum segment lifetime) before returning to CLOSED, which guards against stray duplicate segments from an old connection being misdelivered to a new one reusing the same four-tuple. Understanding this state machine is essential for diagnosing issues like sockets stuck in CLOSE_WAIT (an application not calling close()), TIME_WAIT exhaustion under high connection churn, or half-open connections after a crash.

  • Precisely defines connection lifecycle from open to close
  • Explains why closing uses a different path than opening
  • Provides vocabulary for diagnosing stuck or leaked connections
  • TIME_WAIT protects against stray segments from old connections

AI Mentor Explanation

The TCP state machine is like the formal sequence of a match: WAITING (teams arrive), TOSS_DONE (captains agree who bats), IN_PLAY (overs bowled), INNINGS_BREAK (transition state), and finally MATCH_ENDED, with strict rules about which transitions are legal. You cannot skip from WAITING straight to MATCH_ENDED, and after the match there is a mandatory post-match presentation window before the ground is considered free for the next fixture, just like TIME_WAIT holds a connection briefly before full closure. Each transition happens only on a specific trigger, like the umpire’s signal, mirroring how a TCP state changes only on a specific segment like SYN, ACK, or FIN. Groundstaff tracking exactly which phase a match is in is exactly what a TCP stack does with connection state.

Step-by-Step Explanation

  1. Step 1

    Opening states

    Server: LISTEN → SYN_RECEIVED; Client: CLOSED → SYN_SENT; both reach ESTABLISHED after the handshake completes.

  2. Step 2

    Data transfer

    ESTABLISHED is the stable state where the application reads and writes bytes over the connection.

  3. Step 3

    Active close path

    The initiator sends FIN, moving FIN_WAIT_1 → FIN_WAIT_2 as its FIN and the peer's FIN/ACK are exchanged.

  4. Step 4

    Passive close and TIME_WAIT

    The peer moves CLOSE_WAIT → LAST_ACK; the initiator ends in TIME_WAIT for 2×MSL before returning to CLOSED.

What Interviewer Expects

  • Names the key states in the correct order (LISTEN, SYN_SENT, SYN_RECEIVED, ESTABLISHED, FIN_WAIT_1/2, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSED)
  • Distinguishes the active-close path from the passive-close path
  • Explains the purpose of TIME_WAIT (2×MSL, guarding against stray segments)
  • Can connect the state machine to real debugging (stuck CLOSE_WAIT, TIME_WAIT exhaustion)

Common Mistakes

  • Thinking closing uses the same three steps as the opening handshake
  • Forgetting TIME_WAIT exists or misunderstanding its purpose
  • Confusing CLOSE_WAIT (peer's state) with FIN_WAIT states (initiator's state)
  • Not knowing which side ends up in TIME_WAIT

Best Answer (HR Friendly)

The TCP state machine is the set of well-defined stages a connection passes through — starting, being open, and then closing — and the rules for exactly when it is allowed to move from one stage to the next. It matters because when something goes wrong, like a connection getting stuck, engineers can look at which state it is frozen in to figure out exactly what is failing.

Code Example

Observing TCP connection states
# List sockets with their current TCP state
ss -tan
# State      Recv-Q Send-Q Local Address:Port   Peer Address:Port
# LISTEN     0      128    0.0.0.0:80            0.0.0.0:*
# ESTABLISHED 0     0      10.0.0.5:51422        93.184.216.34:443
# TIME_WAIT  0      0      10.0.0.5:51500        93.184.216.34:443

# Count connections grouped by state
ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c

# Watch for sockets stuck in CLOSE_WAIT (often an app bug)
watch -n2 "ss -tan state close-wait"

Follow-up Questions

  • What is the difference between simultaneous close and the standard four-step close?
  • Why is TIME_WAIT set to roughly 2×MSL rather than a fixed short value?
  • What causes sockets to accumulate in CLOSE_WAIT, and how do you fix it?
  • How does a half-open connection occur, and how does TCP eventually detect it?

MCQ Practice

1. Which state does the endpoint that first calls close() enter after sending its FIN?

The active closer moves to FIN_WAIT_1 immediately after sending its own FIN.

2. What is the primary purpose of the TIME_WAIT state?

TIME_WAIT persists for roughly twice the maximum segment lifetime to guard against delayed duplicate segments.

3. A socket stuck permanently in CLOSE_WAIT usually indicates what?

CLOSE_WAIT means the peer already sent FIN; if the local app never calls close(), the socket stays stuck there.

Flash Cards

Key opening states?LISTEN, SYN_SENT, SYN_RECEIVED, ESTABLISHED.

Active closer's state path?FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED.

Passive closer's state path?CLOSE_WAIT → LAST_ACK → CLOSED.

Why TIME_WAIT?Waits ~2×MSL to prevent stray old-connection segments from corrupting a new connection on the same four-tuple.

1 / 4

Continue Learning