TCP 4-Way Handshake와 TIME_WAIT
TCP 연결을 종료하는 4-way handshake의 단계별 상태와 TIME_WAIT로 대기하는 이유, 빠르게 연결을 끊는 방법을 정리한다.
시리즈 · 네트워크6 / 12
- OSI 7 Layer와 계층별 역할, ARP
- IP 주소: IPv4와 IPv6, NAT, 체크섬
- 라우터: 경로 지정, 브로드캐스트 컨트롤, 라우팅과 스위칭
- DHCP 동작 방식과 UDP를 사용하는 이유
- IP의 한계와 TCP·UDP, 3-Way Handshake
- TCP 4-Way Handshake와 TIME_WAIT
- DNS 정리: 구조, 질의 방식, 레코드, 이중화와 위임
- 로드 밸런서: 구성 방식, 헬스 체크, L4와 L7
- HTTP 메서드와 상태 코드: 멱등성, POST와 PUT의 차이
- HTTP의 Stateless·Connectionless와 쿠키, 세션
- HTTP/1.1, HTTP/2, HTTP/3 비교
- 소켓과 포트, 그리고 웹소켓
4-Way Handshake
4-way handshake는 TCP에서 클라이언트와 서버가 연결을 해제할 때 사용하는 절차다. 연결을 맺는 과정과 TCP 플래그는 IP의 한계와 TCP·UDP, 3-Way Handshake에 정리했다.
종료 과정

클라이언트가 먼저 종료를 요청한다고 하자.
- 클라이언트가 서버에
FIN을 보내고FIN_WAIT_1상태가 된다. - 서버는
FIN을 받고 응답으로ACK를 보낸 뒤CLOSE_WAIT상태가 된다. ACK를 받은 클라이언트는FIN_WAIT_2상태가 된다. - 서버는 연결을 종료할 준비가 되면 클라이언트에게
FIN을 보내고LAST_ACK상태가 된다. (그림에는 LAST_WAIT로 표기되어 있다.) - 클라이언트는
ACK를 보내고TIME_WAIT상태가 된다. ACK를 받은 서버는CLOSED상태가 된다. - 클라이언트는 일정 시간을 기다린 뒤
CLOSED상태가 된다.
패킷이 4-way handshake 목적인지 파악하는 방법
패킷의 헤더를 분석하면 된다. TCP 헤더의 플래그에서 SYN은 연결을 설정하려는 패킷, FIN은 연결을 종료하려는 패킷임을 나타내므로, 플래그를 보면 종료 절차의 패킷인지 알 수 있다.
TIME_WAIT 상태로 대기하는 이유
클라이언트가 마지막으로 보낸 ACK가 네트워크 오류 등으로 서버에 도착하지 않는 경우를 고려한 것이다.
- 서버는 ACK를 받지 못하면 클라이언트가 FIN을 받지 못했다고 간주하고, TCP의 신뢰성을 위해 FIN을 다시 보낸다.
- 클라이언트가 이미 연결을 닫아 버렸다면, 같은 주소와 포트로 새로 맺은 연결이 연결되자마자 이 FIN을 받고 끊어지는 상황이 생길 수 있다.
그래서 클라이언트도 서버가 ACK를 받았는지 확인할 수 있도록 충분한 시간을 기다린다. 대기 시간은 2MSL이며, MSL(Maximum Segment Lifetime)은 세그먼트가 네트워크에 존재할 수 있는 최대 수명을 뜻한다.
4-way handshake를 할 여유 없이 빨리 끊어야 한다면
RST 패킷 전송
연결을 끊는 쪽에서 RST 패킷을 보내면, 상대방은 종료 절차를 기다리지 않고 바로 연결을 끊는다.
SO_LINGER
TCP 소켓 옵션이다. 소켓을 닫을 때 정상적인 종료 절차 대신 즉시 연결을 끊도록 설정할 수 있어, 커넥션이 잦은 서버에서 TIME_WAIT 상태를 없애기 위한 기법으로 쓰인다.
종료 과정 중간에 한쪽 네트워크가 강제로 끊긴다면
다른 쪽은 연결이 아직 활성화되어 있다고 인식해 계속 기다린다. 이를 막는 방법은 두 가지다.
Timeout 설정
일정 시간 동안 상대방으로부터 패킷을 받지 못하면 연결이 종료된 것으로 간주한다.
Keep-alive 메시지
일정한 시간마다 보내는 특별한 패킷이다.
- 상대방이 응답하지 않으면 연결이 종료된 것으로 간주한다.
- 불필요한 트래픽을 유발할 수 있다.