TCP 4-Way Handshake는 TCP 연결을 안전하게 종료하기 위해 네 단계의 패킷을 교환하는 과정입니다.
TCP는 양방향 통신을 지원합니다. 연결을 종료할 때는 각 방향을 독립적으로 닫아야 합니다. 한쪽이 "더 이상 보낼 데이터가 없다"고 선언해도, 상대방은 아직 보낼 데이터가 남아 있을 수 있습니다. 이를 처리하면 4단계가 됩니다.
클라이언트 서버
│ │
│──── FIN ──────────────────────→ │ 1단계: 클라이언트 종료 요청
│ │
│ ←── ACK ────────────────────── │ 2단계: 서버가 요청 수신 확인
│ │
│ (서버 남은 데이터 전송 가능) │
│ │
│ ←── FIN ────────────────────── │ 3단계: 서버 종료 요청
│ │
│──── ACK ──────────────────────→ │ 4단계: 클라이언트 수신 확인
│ │
│ [연결 종료] │
FIN (Finish): TCP 연결 종료를 요청하는 플래그
클라이언트가 더 이상 보낼 데이터가 없음을 알립니다. 그러나 아직 수신은 가능한 상태입니다.
서버가 FIN을 받았음을 확인합니다. 서버는 아직 전송 중인 데이터가 있을 수 있어 즉시 연결을 끊지 않습니다.
서버의 데이터 전송이 완료되면, 서버도 FIN을 보내 종료를 요청합니다.
클라이언트가 서버의 FIN을 확인합니다. 이 ACK 전송 후 클라이언트는 TIME-WAIT 상태로 진입합니다.
마지막 ACK가 유실되어 서버가 FIN을 재전송할 경우를 대비합니다. 일반적으로 2MSL(Maximum Segment Lifetime, 보통 60~120초) 동안 유지합니다. 이 시간 동안 같은 포트로 새 연결을 열 수 없습니다.
서버를 빠르게 재시작해야 할 때 SO_REUSEADDR 소켓 옵션으로 TIME-WAIT 중인 포트를 재사용할 수 있습니다.
서버가 FIN을 받았지만 아직 FIN을 보내지 않은 상태입니다. 서버 애플리케이션이 연결을 제대로 닫지 않으면 CLOSE-WAIT 상태가 쌓입니다. 서버의 연결 자원 고갈로 이어질 수 있어 주의가 필요합니다.
한 방향만 종료하는 것도 가능합니다. 클라이언트가 FIN을 보내 더 이상 데이터를 보내지 않겠다고 해도, 서버의 데이터는 계속 받을 수 있습니다. 파일 업로드 후 서버 응답을 기다리는 패턴에서 활용됩니다.