핵심 인사이트 (3줄 요약)

  1. 본질: TCP 4-Way Handshake는 클라이언트와 서버가 서로 볼일이 다 끝났을 때, 갑자기 전화를 확 끊어버려서 상대방이 마지막으로 하려던 말을 못 듣는 참사를 막기 위해, 서로 4번에 걸쳐 "나 할 말 다 했어(FIN)", "응 알았어(ACK)"를 아주 정중하게 교환하며 세션을 우아하게 닫는 종료 의식이다.
  2. 반쪽짜리 닫힘 (Half-Close): 클라이언트가 먼저 "나 끊을게(FIN)"라고 해도, 서버는 "어 그래? 난 아직 너한테 보내줄 파일이 좀 남았는데? 이거 마저 다 보내고 끊을게!"라며 한쪽 방향은 닫혔지만 반대쪽 방향은 살아있는 '반쪽짜리 통신' 상태를 허용하는 것이 가장 큰 특징이다.
  3. 서버의 최종 FIN: 서버마저 남은 찌꺼기 파일을 다 보내고 나면, 비로소 자기도 "나도 이제 진짜 다 보냈어 끊자!(FIN)"라고 선언하고 클라이언트의 마지막 응답(ACK)을 받아야만 통신이 100% 영구적으로 소멸한다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: TCP 세션(연결)을 정상적으로 해제하기 위해, 양 종단 간에 FINACK 제어 플래그를 4단계에 걸쳐 교환하여, 상호 간에 송신할 데이터가 없음을 확인하는 과정 (Graceful Teardown).

  • 필요성: 나쁜 이별(RST 패킷)은 그냥 멱살 잡고 "다 꺼져!" 하고 스위치를 뽑아버리면 끝난다. 하지만 좋은 이별은 준비가 필요하다. 내 PC는 카카오톡 사진 전송을 다 끝내서 끊고 싶은데, 카카오 서버는 나한테 줄 메시지 3개가 큐(대기열)에 남아 있을 수 있다. 만약 내가 3번 악수(3-Way)처럼 [FIN] 쏘고 서버가 [FIN+ACK] 쏘고 끝내버리면, 서버에 남아있던 메시지 3개는 영원히 증발해 버린다. **"내가 먼저 끊자고 해도, 혹시 상대방이 나한테 덜 준 데이터가 있으면 그거 다 받을 때까지 얌전히 기다려 주자!"**라는 예의 바른 설계가 4번의 악수를 만들어냈다.

  • 💡 비유: 4-Way Handshake는 예의 바른 사람들의 **"전화 끊기 과정"**과 완벽히 일치합니다.

    • A: "나 할 말 다 했어. 이제 전화 끊자~ (FIN)"
    • B: "어 알았어, 끊자! (ACK) ... 근데 잠깐만!! 아까 말 안 한 게 있는데~~ 쏼라쏼라~~ (남은 데이터 전송)"
    • A: "아 그래? (가만히 다 들어줌 = Half-Close 상태)"
    • B: "응 이제 나도 진짜 할 말 다 끝났어. 찐으로 끊자~ (FIN)"
    • A: "오케이~ 진짜 끊는다 뚝! (ACK)"

📢 섹션 요약 비유: 4단계 종료 과정은 뷔페 식당의 **"영업 종료 안내"**입니다. 지배인이 "영업 끝났습니다(FIN)"라고 안내해도, 손님 입의 음식을 뺏진 않습니다. 손님은 "네 알겠습니다(ACK)"라고 한 뒤, 접시에 남은 고기(남은 데이터)를 천천히 다 먹고 나서야 "잘 먹고 갑니다(FIN)"라고 인사하고, 지배인이 "안녕히 가세요(ACK)" 해야 비로소 문이 닫힙니다.


Ⅱ. 4단계 동작 메커니즘과 상태 변화 (Deep Dive)

이 4단계를 외우지 못하면 네트워크 면접에서 광탈한다. 누가 먼저 끊자고(Active Close) 제안했는지 클라이언트 입장에서 따라가 보자.

1단계: 클라이언트의 이별 통보 (FIN)

  • 클라이언트는 더 보낼 게 없다.
  • 패킷 헤더에 FIN 불을 켜서 서버로 날린다.
  • 상태 변화: 클라이언트는 FIN_WAIT_1 상태로 진입하여 상대방의 첫 대답을 기다린다.

2단계: 서버의 일단 수긍 (ACK)

  • 서버가 FIN을 받았다. "오케이 네가 끊고 싶은 건 알겠어."
  • 서버는 일단 ACK 불을 켜서 대답만 먼저 해준다.
  • 상태 변화:
    • 서버는 CLOSE_WAIT 상태가 된다. (이게 핵심이다! "어? 나 얘한테 보낼 데이터 램에 좀 남아있는데? 프로세스(앱)야, 빨리 남은 데이터 다 뿜어내서 정리해 줘!"라며 앱의 종료를 기다리는 상태다).
    • 클라이언트는 ACK를 받고 FIN_WAIT_2 상태가 되어 서버의 진짜 마지막 인사를 기다린다. (이때 클라이언트의 쏘는 입은 닫혔지만, 서버가 보내는 패킷을 '듣는 귀'는 활짝 열려 있다 = Half-Close).

3단계: 서버의 찐막 인사 (FIN)

  • 서버 측 앱이 남은 데이터를 싹 다 보냈다. "나도 이제 진짜 끝!"
  • 서버는 자기 패킷 헤더에 FIN 불을 켜서 클라이언트로 쏜다.
  • 상태 변화: 서버는 LAST_ACK 상태가 되어 클라이언트의 마지막 영수증만 기다린다.

4단계: 클라이언트의 최종 수신 확인 (ACK)

  • 클라이언트가 서버의 찐막 FIN을 받았다.
  • 클라이언트는 "그래 수고했어!"라며 ACK 불을 켜서 서버로 쏜다.
  • 상태 변화 (매우 중요):
    • 서버는 이 ACK를 받으면 미련 없이 소켓 메모리를 삭제하고 CLOSED (완전 소멸) 된다.
    • 클라이언트는 이 ACK를 쏘고 나서 바로 꺼지지 않는다! **TIME_WAIT**라는 특수 상태에 빠져서 허공을 멍하니 1분 이상 쳐다보며 대기한다. (왜 대기하는지는 다음 장에서 배운다).
 ┌─────────────────────────────────────────────────────────────┐
 │                TCP 4-Way Handshake 상태 변화 흐름도              │
 ├─────────────────────────────────────────────────────────────┤
 │                                                             │
 │   [ 클라이언트 (Active Close) ]               [ 서버 (Passive Close) ]│
 │      (ESTABLISHED)                            (ESTABLISHED) │
 │           │                                         │       │
 │           │ 1. [FIN] "나 끊을게"                      │       │
 │           ├───────────────────────────────────────▶ │       │
 │    (FIN_WAIT_1)                               (CLOSE_WAIT)  │
 │           │ 2. [ACK] "어 알았어 (근데 남은 거 줌)"       │       │
 │           ◀───────────────────────────────────────┤       │
 │    (FIN_WAIT_2)                                     │       │
 │           │         ... (남은 데이터 찌꺼기 전송) ...   │       │
 │           │                                         │       │
 │           │ 3. [FIN] "나도 다 줬다 찐막 끊자!"         │       │
 │           ◀───────────────────────────────────────┤       │
 │    (TIME_WAIT)                                 (LAST_ACK)   │
 │           │ 4. [ACK] "잘 가~!"                      │       │
 │           ├───────────────────────────────────────▶ │       │
 │           │                                      (CLOSED)   │
 │    (2MSL 대기 후 CLOSED)                                     │
 └─────────────────────────────────────────────────────────────┘

📢 섹션 요약 비유: 4-Way Handshake는 무전기 통신의 **"오버 앤 아웃"**입니다. 내가 "할 말 다 했음, 오버(FIN)"라고 하면 상대는 "알겠음, 근데 내 할 말은 어쩌고 저쩌고~ 끝, 오버(FIN)"라고 합니다. 마지막으로 내가 "다 잘 들었음, 통신 끝 아웃!(ACK)"이라고 해야 비로소 무전기의 전원이 완전히 꺼집니다.