ArcLibrary

TCP Three-Way Handshake & Four-Way Termination

Why setup needs 3 steps and teardown needs 4 — the heart of TCP's state machine.

TCPHandshakeState Machine
核心 · Key Idea

In one line: the three-way handshake lets each side confirm "I can send / you can receive / you can send / I can receive"; the four-way termination exists because TCP is full duplex — each direction is closed independently.

What it is#

Handshake:
  C → S  SYN seq=x
  C ← S  SYN+ACK seq=y, ack=x+1
  C → S  ACK ack=y+1
  Connection established.

Termination:
  C → S  FIN
  C ← S  ACK         (got it; let me finish flushing)
  C ← S  FIN         (I'm done too)
  C → S  ACK
  Connection closed.

Analogy#

打个比方 · Analogy

Handshake = a phone call: "Hello?" "Hi!" "OK, let's talk." Each side checks "I can hear + you can hear" once. Termination = both sides agreeing to hang up: "I'm done speaking." "OK, let me finish too." (more bytes possible in between) "I'm done too." "OK, hanging up."

Key concepts#

SYNSynchronize
Step one — request to open, carries an initial sequence number.
ACKAcknowledge
Confirms receipt of a byte range. Every TCP segment carries an ACK field.
FINFinish
I'm done sending in this direction.
TIME_WAITTime Wait
Active closer waits 2*MSL (~60 s) before fully releasing — prevents stale segments from confusing a new connection on the same tuple.
Half-closeHalf-close
After one side FINs, the other can keep sending.
RSTReset
Forced abort, skips the four-way dance — common on closed ports / abnormal exits.

State machine#

In production, the two most common pains are TIME_WAIT accumulation (high-concurrency short-lived connections) and CLOSE_WAIT lingering (the app never called close()).

Practical notes#

  • netstat -an | awk '{print $6}' | sort | uniq -c — connection count per state.
  • Too many TIME_WAITs? Enable tcp_tw_reuse on Linux to recycle. Avoid tcp_tw_recycle (removed since 4.12 — broke connectivity behind NAT).
  • CLOSE_WAIT is a bug. Your app received the peer's FIN but never called close(). Use lsof to find the leak.
  • SYN flood: forged SYNs fill the half-open queue. Enable syncookies as a defense.
  • TFO (TCP Fast Open): payload travels with the handshake, saving 1 RTT — but middleboxes / peers spotty support, not widely deployed.

Easy confusions#

Graceful FIN close
Four-way teardown, **pending data delivered**.
Application called close().
RST abort
Single RST packet, **unsent data may be lost**.
Port not listening / app crashed / SO_LINGER 0.

Further reading#