Octet

How does a TCP connection close? Walk through the four-way close and the states on each side.

Show the answer

Say this first

Each direction closes on its own with a FIN. The side that closes first sends FIN and enters FIN_WAIT_1. The peer ACKs it and enters CLOSE_WAIT; the first side moves to FIN_WAIT_2. When the peer's application closes, the peer sends its own FIN and enters LAST_ACK. The first side ACKs that FIN and sits in TIME_WAIT for two maximum segment lifetimes; the peer goes to CLOSED when that ACK arrives.

Go deeper

The sequence

Output
Active closer (A)                         Passive closer (B)
ESTABLISHED                               ESTABLISHED
  FIN  ->
FIN_WAIT_1                                CLOSE_WAIT   (B's app is told: end of stream)
                <-  ACK
FIN_WAIT_2                                 ... B may keep sending data ...
                <-  FIN                   LAST_ACK     (B's app called close())
TIME_WAIT
  ACK  ->                                 CLOSED
(after 2 x MSL) CLOSED

Three segments instead of four

If B's application closes straight away, B sends its FIN in the same segment as the ACK. A capture then shows [F.], [F.], [.]. That is still the same state machine, just with the ACK and FIN combined.

Half-close

Between FIN_WAIT_2 and LAST_ACK, B can still send data and A must still receive and acknowledge it. shutdown(SHUT_WR) uses this on purpose: "I have finished sending, now give me the result".

Simultaneous close

If both sides send FIN at the same time, each goes FIN_WAIT_1, then CLOSING when it receives the other's FIN, then TIME_WAIT when its own FIN is acknowledged. Both sides end in TIME_WAIT.

Traps

  • Mixing up CLOSE_WAIT and TIME_WAIT. CLOSE_WAIT is on the passive side waiting for its own app; TIME_WAIT is on the active side after the close.
  • Saying a FIN closes the connection in both directions. It only ends the sender's direction.
How did you do?Book 5.2 Reliable Byte Stream (TCP)