TIME_WAIT
is different from CLOSE_WAIT
, and it’s not necessarily a client-side fault. It happens due to how TCP handles connection termination.
Key Differences
TCP State | Cause | Who is responsible? | Fix/Optimization |
---|---|---|---|
CLOSE_WAIT | Server didn’t close() the socket after client closed it. | Server-side issue (socket left open). | Ensure close(client_fd); is always called. |
TIME_WAIT | Server closed the socket first, waiting to ensure the client received the FIN. | Normal behavior (not necessarily a problem). | Use SO_LINGER or SO_REUSEADDR to mitigate excessive TIME_WAIT . |
Why Does TIME_WAIT Happen?
- When your server calls
close(client_fd);
, it sends aFIN
to the client. - If the client follows the normal TCP closure process, it replies with
ACK
and sends its ownFIN
, which your server thenACK
s. - Your server enters
TIME_WAIT
for 2×MSL (Maximum Segment Lifetime, usually 60s total) to ensure any delayed packets are handled before fully releasing the connection.
Is TIME_WAIT the Client’s Fault?
- If the client closes the connection first, the server goes to
CLOSE_WAIT
(which we fixed). - If the server closes first,
TIME_WAIT
is expected. - Too many TIME_WAIT sockets? It usually means many short-lived connections are being closed quickly.
How to Reduce TIME_WAIT Issues?
-
Enable
SO_REUSEADDR
- Allows immediate reuse of the same port, even in
TIME_WAIT
state.
int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
- Allows immediate reuse of the same port, even in
-
Use
SO_LINGER
to Force Immediate Closure- Not recommended unless necessary, as it can cause packet loss.
struct linger sl; sl.l_onoff = 1; // Enable linger sl.l_linger = 2; // Close socket after 2 seconds setsockopt(client_fd, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl));
-
Keep Connections Open Longer
- If possible, reuse connections instead of opening/closing frequently.
-
Tune TCP Stack (
sysctl
)- Reduce
TIME_WAIT
timeout if necessary:
sudo sysctl -p | grep net.ipv4.tcp_fin_timeout # net.ipv4.tcp_fin_timeout = 2 sysctl -w net.ipv4.tcp_fin_timeout=30
- Reduce
Conclusion
CLOSE_WAIT
is a server-side issue (fixed by properly closing sockets).TIME_WAIT
is expected behavior when the server closes first.- Too many
TIME_WAIT
sockets? UseSO_REUSEADDR
, linger options, or connection pooling if appropriate.