TCP `4-way handshaking` 완전 정복 — `FIN`, `ACK`, `TIME_WAIT`까지
4-way handshaking, 왜 따로 알아야 하나요?
TCP vs UDP 글까지 읽고 나면 이런 질문이 남습니다.
3-way handshake는 많이 들어봤는데,4-way handshaking은 정확히 무엇일까요?- 왜 연결을 닫는 데는
SYN,ACK처럼 세 번이 아니라 네 번이 필요할까요? - 서버에
CLOSE_WAIT가 많이 쌓였다는 말은 무슨 뜻일까요? TIME_WAIT는 왜 마지막에 꼭 남고, 언제 문제처럼 보일까요?FIN으로 닫는 것과RST로 끊는 것은 무엇이 다를까요?
핵심은 이것입니다.
TCP연결 종료는 "한 번에 끊는 동작"이 아니라, 양방향 스트림을 각각 독립적으로 닫아 가는 과정입니다
즉:
TCP는 양방향 통신이고- 내가 보내는 방향과 상대가 보내는 방향은 따로 닫을 수 있으며
- 그래서 연결 종료도 보통
FIN과ACK가 나뉘어 오가게 됩니다
이 글에서는 4-way handshaking을 단순 암기 절차로 보지 않고, 왜 FIN과 ACK가 네 번 오가는지, half-close, TIME_WAIT, CLOSE_WAIT, RST와 어떤 관계가 있는지 를 기준으로 정리하겠습니다.
기준: 이 글은
TCP연결 종료 동작을RFC 9293기준으로 설명합니다. 표현상4-way handshaking이라고 부르지만, RFC는 보통 normal close sequence using aFINhandshake 라고 설명합니다.
먼저 가장 짧은 답부터 보면
실무에서는 아래 정도만 먼저 잡아도 큰 틀은 흔들리지 않습니다.
| 질문 | 짧은 답 |
|---|---|
4-way handshaking이란? |
TCP 연결을 정상 종료할 때 FIN/ACK를 교환하는 대표 흐름 |
| 왜 네 번인가? | 양방향 스트림을 각각 닫아야 해서 ACK와 반대편 FIN이 분리될 수 있기 때문 |
누가 TIME_WAIT에 들어가나? |
보통 active close 를 시작한 쪽 |
CLOSE_WAIT는 왜 쌓이나? |
원격 FIN은 받았지만 로컬 애플리케이션이 자기 쪽 close를 안 했기 때문 |
RST와 차이는? |
FIN은 정상 종료, RST는 연결을 즉시 중단하는 abort에 가깝습니다 |
가장 짧게 줄이면 이렇습니다.
4-way handshaking은TCP의 정상 종료 절차입니다- 핵심은 "양쪽이 각자 보내던 방향을 따로 닫는다"는 점입니다
- 그래서
TIME_WAIT,CLOSE_WAIT같은 상태도 종료 과정의 일부로 이해해야 합니다
Phase 1. 왜 연결 종료는 시작보다 더 복잡해 보일까?
3-way handshake는 연결을 시작하는 절차입니다. 이때는 양쪽이 "이제 연결을 만들자"는 데 동의하면 됩니다.
반면 종료는 조금 다릅니다.
연결 종료는 "앞으로 더 보낼 데이터가 없다"는 사실을 각 방향마다 따로 합의해야 합니다
즉, TCP에서는:
- 내가 보내는 스트림
- 상대가 보내는 스트림
이 독립적으로 닫힐 수 있습니다.
그래서 한쪽이 먼저:
나는 더 이상 보낼 데이터가 없습니다
라고 말해도, 상대는 아직:
나는 보낼 데이터가 남아 있습니다
라고 할 수 있습니다.
이 특성 때문에 종료는 보통 한 번에 끝나지 않고, 한 방향 종료 확인 + 반대 방향 종료 확인 으로 나뉩니다.
Phase 2. FIN과 ACK는 각각 무엇을 뜻할까?
4-way handshaking을 이해하려면 FIN과 ACK를 정확히 나눠 봐야 합니다.
FIN은 "더 보낼 데이터가 없다"는 뜻이다
FIN은 대충 "연결 끊자"가 아닙니다. 더 정확히는:
이 방향으로는 더 이상 보낼 사용자 데이터가 없습니다
라는 뜻입니다.
그래서 한쪽이 FIN을 보냈다고 해서, 연결 전체가 즉시 사라지는 것은 아닙니다.
상대는 여전히:
- 지금까지 받은 데이터는 읽어야 하고
- 자기가 남은 데이터를 보낼 수도 있습니다
ACK는 "네 FIN은 받았다"는 뜻이다
상대가 ACK를 보내면, 이는 보통:
네가 더 이상 안 보낸다는 뜻은 알겠다
는 의미입니다.
하지만 이것만으로 상대도 자기 송신을 끝냈다는 뜻은 아닙니다.
즉:
FIN= 나의 송신 종료 선언ACK= 네 종료 선언 수신 확인
으로 보는 편이 정확합니다.
Phase 3. 4-way handshaking은 실제로 어떻게 흐를까?
가장 흔한 정상 종료 흐름은 아래처럼 그릴 수 있습니다.
Client -> Server : FIN
Client <- Server : ACK
Client <- Server : FIN
Client -> Server : ACK
이걸 단계별로 풀면 이렇습니다.
1. 먼저 닫고 싶은 쪽이 FIN을 보낸다
예를 들어 클라이언트가 먼저 요청/응답을 다 마쳤고 더 보낼 데이터가 없다고 가정해 보겠습니다.
그러면:
Client -> Server : FIN
을 보냅니다.
이 순간 클라이언트는 보통 FIN-WAIT-1 같은 상태로 들어가며, 자기 송신 방향을 닫기 시작한 상태가 됩니다.
2. 상대는 ACK로 받았다고 답한다
서버는 이 FIN을 받으면:
Client <- Server : ACK
를 보냅니다.
이 뜻은:
- 클라이언트의 송신 종료 선언은 받았고
- 하지만 서버 자신은 아직 보낼 것이 남아 있을 수 있다는 뜻
입니다.
이 시점이 바로 half-close를 이해하는 핵심입니다.
3. 상대가 자기 송신도 끝낼 때 FIN을 보낸다
서버 애플리케이션도 응답을 다 마쳤거나 더 보낼 데이터가 없어지면:
Client <- Server : FIN
을 보냅니다.
즉, 서버도 이제 자기 방향 송신을 닫습니다.
4. 마지막으로 ACK를 보내고 종료를 확정한다
클라이언트는 마지막으로:
Client -> Server : ACK
를 보내고, 정상 종료 시퀀스가 마무리됩니다.
다만 여기서 끝난 것처럼 보여도, active close를 시작한 쪽은 보통 바로 사라지지 않고 TIME_WAIT에 들어갑니다.
Phase 4. 왜 정확히 네 번이어야 할까?
여기서 자주 나오는 질문이 이것입니다.
왜
3-way handshake는 세 번인데 종료는 네 번일까?
핵심은 시작과 종료의 대칭성이 완전히 같지 않기 때문입니다.
연결 시작에서는:
- 서로 연결을 만들 준비가 되었는지
- 초기 시퀀스 상태를 맞추는지
를 빠르게 합의하면 됩니다.
반면 연결 종료에서는:
- 내 송신 종료
- 네 송신 종료
가 분리될 수 있습니다.
그래서 상대는 내 FIN을 받자마자:
ACK로 먼저 응답하고- 자기 애플리케이션이 실제로 닫을 준비가 되었을 때 나중에
FIN을 보낼 수 있습니다
즉, ACK와 반대편 FIN이 논리적으로 분리될 수 있어서 네 단계처럼 보이는 것입니다.
꼭 항상 패킷 네 개가 보이느냐?
엄밀히 말하면, 캡처에서는 상황에 따라 ACK와 FIN이 같은 세그먼트에 함께 실려 보일 수도 있습니다.
예를 들어 RFC 9293의 normal close 예시에서도 FIN,ACK 형태가 등장합니다.
즉:
- 흔히 설명할 때는
FIN -> ACK -> FIN -> ACK네 단계로 이해하고 - 실제 패킷 단위에서는
ACK가 다른 제어 비트와 합쳐질 수 있으며 - 동시에 닫으면
CLOSING같은 다른 상태 흐름도 나올 수 있습니다
그래서 4-way handshaking은 개념적 종료 절차로 이해하는 편이 정확합니다.
Phase 5. half-close는 정확히 무엇일까?
TCP 종료를 이해할 때 중요한 개념이 half-close입니다.
한쪽이 FIN을 보내면, 그쪽은:
- 더 이상 보내지는 않지만
- 상대가 보내는 데이터는 아직 받을 수 있습니다
즉, 연결 전체가 죽은 것이 아니라 한 방향만 먼저 닫힌 상태가 됩니다.
예를 들어:
- 클라이언트가 요청 바디를 다 보냄
FIN전송- 서버는 그 요청을 다 읽고 처리
- 응답을 보낸 뒤 자기
FIN전송
같은 흐름이 가능합니다.
즉, half-close는 이상한 예외가 아니라, TCP 종료가 양방향 독립이라는 사실의 자연스러운 결과입니다.
Phase 6. TIME_WAIT는 왜 남을까?
실무에서 가장 많이 보이는 종료 관련 상태는 TIME_WAIT입니다.
TIME_WAIT는 active close 쪽에서 주로 보인다
RFC 9293 기준으로 normal close sequence에서 먼저 닫기를 시작한 쪽은 마지막 ACK를 보낸 뒤 TIME_WAIT에 들어갑니다.
이 상태의 목적은 크게 두 가지입니다.
- 마지막
ACK가 상대에게 도달했는지 여유를 둔다 - 이전 연결의 지연 세그먼트가 새 연결과 섞이지 않게 한다
RFC 9293도 TIME-WAIT를, 원격 피어가 종료 요청에 대한 ACK를 받았는지 충분한 시간을 기다리고 지연 세그먼트의 영향을 피하기 위한 상태로 설명합니다.
그래서 왜 2MSL 이야기가 나올까?
보통 TIME_WAIT는 2MSL과 함께 설명됩니다.
MSL은 최대 세그먼트 생존 시간 개념이고2MSL은 패킷 왕복 지연과 지연 세그먼트 정리를 고려한 대기 시간입니다
즉, TIME_WAIT는 "쓸데없이 남는 상태"가 아니라, 정상 종료를 안전하게 마무리하기 위한 완충 구간입니다.
언제 문제처럼 보일까?
실무에서는:
- 짧은 연결이 매우 많고
- active close를 애플리케이션이 계속 하고
- 포트 재사용 압박이 있는 환경
에서 TIME_WAIT가 많아 보일 수 있습니다.
하지만 상태가 많다는 사실 자체가 곧 버그는 아닙니다. 오히려 정상 종료가 잘 되고 있다는 흔적일 수도 있습니다.
Phase 7. CLOSE_WAIT는 왜 쌓일까?
이건 TIME_WAIT보다 더 자주 진짜 문제입니다.
CLOSE_WAIT는 원격 FIN은 받았는데, 로컬이 아직 안 닫았다는 뜻이다
상대가 FIN을 보내면 로컬 커널은 이를 ACK하고, 애플리케이션에게 연결이 닫히는 중이라고 알립니다.
이후 애플리케이션이 자기 쪽 close를 호출해야:
FIN을 보내고LAST-ACK를 거쳐- 완전히 종료됩니다
그런데 애플리케이션이 이 종료를 미루거나 누락하면 CLOSE_WAIT가 오래 남습니다.
즉:
CLOSE_WAIT가 많이 쌓인다는 것은 대개 네트워크 문제보다 애플리케이션이 소켓을 제대로 닫지 않는 문제에 가깝습니다
이 때문에 서버 운영에서 CLOSE_WAIT는 진짜 점검 대상이 되는 경우가 많습니다.
Phase 8. FIN 종료와 RST 종료는 어떻게 다를까?
RFC 9293는 TCP 연결 종료를 크게 두 가지로 설명합니다.
- 정상적인
FIN기반 종료 RST를 보내고 상태를 즉시 버리는 abort
FIN은 정상 종료다
FIN 기반 종료는:
- 남아 있는 데이터 순서를 보존하고
- 상대에게 종료 사실을 예고하며
- 정상적으로 정리할 기회를 줍니다
즉, graceful close에 가깝습니다.
RST는 즉시 중단에 가깝다
반면 RST는 보통:
- 연결이 비정상 상태이거나
- 더 이상 정상 종료 절차를 밟지 않고
- 즉시 연결을 끊어야 할 때
사용됩니다.
즉, RST는:
- "정상적으로 다 보냈으니 닫겠습니다"가 아니라
- "이 연결은 더 이상 유효하지 않으니 즉시 버리겠습니다"
에 가깝습니다.
그래서 애플리케이션 관점에서도 FIN 종료와 RST 종료는 같은 일이 아닙니다.
핵심만 다시 정리하면
마지막으로 4-way handshaking을 한 번 더 정리하면 이렇게 볼 수 있습니다.
| 구분 | 의미 |
|---|---|
첫 번째 FIN |
한쪽이 자기 송신 종료를 선언 |
첫 번째 ACK |
상대가 그 종료 선언을 확인 |
두 번째 FIN |
상대도 자기 송신 종료를 선언 |
마지막 ACK |
종료 절차를 최종 확인 |
TIME_WAIT |
active close 쪽이 마지막 정리를 위해 대기 |
CLOSE_WAIT |
원격은 닫았지만 로컬 애플리케이션이 아직 안 닫음 |
핵심 포인트는 다섯 가지입니다.
4-way handshaking은TCP연결을 정상 종료할 때 가장 대표적으로 나타나는 절차입니다.- 종료가 네 단계처럼 보이는 이유는 양방향 스트림을 각각 독립적으로 닫기 때문입니다.
- 한쪽이
FIN을 보냈다고 해서 연결 전체가 즉시 끝나는 것은 아니며, 이 사이에half-close가 가능합니다. TIME_WAIT는 정상 종료를 안전하게 마무리하기 위한 상태이고,CLOSE_WAIT는 대개 애플리케이션의 소켓 정리 누락과 더 관련이 큽니다.FIN종료와RST종료는 다르며,RST는 정상적인 마무리보다 즉시 abort 에 가깝습니다.
결국 4-way handshaking은 "FIN, ACK 네 개를 외우는 절차"가 아니라, TCP가 양방향 스트림을 어떻게 안전하게 접고, 종료 후 지연 세그먼트까지 어떻게 정리하는지 를 보여 주는 상태 전이 과정에 가깝습니다.