A situation
At the end of a phone call, you say "bye", and the other person says "bye" back before you both hang up. They might add one last thing first. Nobody cuts the line in the middle of a sentence, unless something has gone wrong. TCP ends connections in the same polite way, but it also has a way to cut the line immediately.
What it is: the FIN exchange
A TCP connection is really two one-way streams, one in each direction. Each side closes its own stream by sending a segment with the FIN (finish) flag set, and the other side confirms it with an ACK. That makes four messages:
- Client:
- TIME-WAIT, then CLOSED
- Server:
- CLOSED
The server often sends its ACK and FIN together in one segment, so you may see only three messages.
The closing states
The side that sends the first FIN does an active close. The other side does a passive close.
| State | Side | Meaning |
|---|---|---|
FIN-WAIT-1 | Active | Has sent a FIN; waiting for it to be acknowledged |
FIN-WAIT-2 | Active | Its FIN was acknowledged; waiting for the other side's FIN |
CLOSE-WAIT | Passive | Has received a FIN; waiting for its own application to finish and close |
LAST-ACK | Passive | Has sent its own FIN; waiting for the last ACK |
TIME-WAIT | Active | Has sent the last ACK; waits for a while before removing the connection |
Why TIME-WAIT exists
After the final ACK, the active side waits for twice the maximum segment lifetime (MSL), which is the longest time a segment can stay in the network. On many systems, including Linux, this wait is 60 seconds in total. There are two reasons for it:
- If the last ACK is lost, the other side sends its FIN again. The waiting side still remembers the connection, so it can answer.
- Old, delayed segments from this connection expire before a new connection can reuse the same socket pair, so they cannot be mixed into the new connection.
A busy server can show thousands of connections in TIME-WAIT. That is normal. Many connections stuck in CLOSE-WAIT are different: the remote side has closed, but the local application never closed its end. This usually points to a bug in the application.
RST: closing immediately
A reset (a segment with the RST flag set) ends a connection immediately. The other side does not reply and there is no waiting; any data that has not been delivered yet is discarded.
- 1. Closed port. The client tries to connect to a port where no application is listening.
- 2. Refused. The server answers with an RST, and the client reports 'connection refused'.
- 3. Middlebox reset. Some firewalls also send an RST, for example after a long idle time or when a security rule blocks a session that is already open.
How to verify it
On a Cisco router, show tcp brief all lists the router's own TCP sessions (for example, SSH logins to the router) and their states. The output below is based on Cisco documentation, not captured from a lab device.
R1#show tcp brief all TCB Local Address Foreign Address (state) 6523A4FC 10.1.1.1.22 10.1.1.50.51544 ESTAB 65239A84 10.1.1.1.22 10.1.1.51.60212 TIMEWAIT 65241B10 10.1.1.1.179 10.1.1.2.11045 ESTAB 6523F2C8 0.0.0.0.22 *.* LISTEN
ESTAB (open). The second has just been closed by the router, which did the active close, so it stays in TIMEWAIT for a short time. The BGP session (port 179) is open, and LISTEN shows the router waiting for new SSH connections.clear tcp tcb 6523A4FCEnds one TCP session on the router, identified by its TCB number (the router asks you to confirm). The session is ended immediately, without a normal FIN exchange.
Check yourself
Your laptop finishes downloading a page and closes the connection by sending the first FIN. After the exchange, which side stays in TIME-WAIT?
A server shows hundreds of connections in CLOSE-WAIT that never go away. What is the likely cause?
A client sends a FIN, but the server keeps sending data for a few more seconds before it sends its own FIN. Why is this allowed?