TCP 연결 관리: 3-way handshake와 종료

Tasker_Jang·2026년 9월 25일
post-thumbnail

1. 연결을 연다는 것의 의미

TCP에서 "연결"은 회선을 잡아두는 것이 아닙니다. 인터넷은 packet switching이고 코어는 아무 자리도 예약해주지 않습니다. 연결은 오직 양 끝 호스트의 메모리에만 존재합니다.

연결을 연다는 것은 구체적으로 다음을 맞추는 일입니다.

  • 양쪽의 초기 sequence number(ISN)
  • 수신 버퍼와 송신 버퍼의 할당
  • 윈도우 크기 등 연결마다 유지할 변수

이 정보를 담은 커널 내부 자료구조가 3편에서 본 4-tuple로 식별되는 소켓의 실체입니다.

2. 3-way handshake

세 단계 각각이 하는 일이 다릅니다.

  1. 클라이언트가 SYN 비트를 켠 세그먼트를 보냅니다. 여기에 자기 ISN을 담습니다. 데이터는 없지만 sequence number를 하나 소비합니다.
  2. 서버는 SYN과 ACK를 함께 켜서 답합니다. 클라이언트의 ISN에 1을 더한 값을 acknowledgment number에 넣어 "네 시작 번호를 받았다"고 알리고, 동시에 자기 ISN을 실어 보냅니다. 이 시점에 서버는 이 연결을 위한 버퍼와 변수를 할당합니다.
  3. 클라이언트가 서버의 ISN에 1을 더한 ACK를 보냅니다. 이 세그먼트부터는 데이터를 함께 실을 수 있습니다.

ISN을 0부터 시작하지 않고 난수로 잡는 점이 중요합니다. 같은 4-tuple로 연결을 다시 맺었을 때, 이전 연결의 늦게 도착한 세그먼트가 새 연결의 데이터로 오인되는 것을 막기 위해서입니다.

왜 두 번으로는 안 되는지도 같은 맥락입니다. 양쪽이 각자의 ISN을 보내고 각자 확인받아야 하므로 최소 네 번의 교환이 필요한데, 서버의 ACK와 SYN을 한 세그먼트에 합칠 수 있어 세 번이 됩니다.

3. control flag 정리

4편의 헤더 표에서 한 줄로 넘어갔던 flags를 여기서 풀면 다음과 같습니다.

flag의미쓰이는 곳
SYN연결을 시작하고 ISN을 동기화handshake의 앞 두 세그먼트에만
ACKacknowledgment number 필드가 유효함연결 수립 후 거의 모든 세그먼트
FIN더 보낼 데이터가 없음연결 종료
RST연결을 즉시 끊음닫힌 포트로 접속 시도 등 비정상 상황

4. 연결 종료는 왜 네 단계인가

종료는 한쪽이 먼저 끝낸다고 선언하는 것에서 시작합니다.

  1. 클라이언트가 FIN을 보냅니다. "보낼 데이터가 없다"는 뜻입니다.
  2. 서버가 FIN을 받고 ACK로 답합니다. 다만 서버는 아직 보낼 데이터가 남아 있을 수 있습니다.
  3. 서버가 남은 데이터를 다 보낸 뒤 자기 FIN을 보냅니다.
  4. 클라이언트가 ACK로 답합니다.

TCP가 full duplex라 방향이 둘이고, 각 방향을 독립적으로 닫기 때문에 네 단계가 됩니다. 한쪽만 닫힌 상태를 half-close라고 부릅니다. 연결 수립에서는 서버의 ACK와 SYN을 합칠 수 있었지만, 종료에서는 2번과 3번 사이에 남은 데이터를 보낼 시간이 필요해 합쳐지지 않는 것이 일반적입니다.

5. TIME_WAIT과 2MSL

먼저 FIN을 보낸 쪽은 마지막 ACK를 보낸 뒤 바로 사라지지 않고 TIME_WAIT 상태로 일정 시간 머뭅니다. 기다리는 시간은 MSL(Maximum Segment Lifetime, 세그먼트 최대 생존 시간)의 두 배입니다.

이유는 두 가지입니다. 첫째, 마지막 ACK가 유실되면 상대는 FIN을 재전송하는데, 이미 소켓을 지워버렸다면 응답할 주체가 없습니다. 둘째, 네트워크 어딘가에서 헤매던 옛 세그먼트가 뒤늦게 도착해 같은 4-tuple의 새 연결을 오염시키는 것을 막습니다. 왕복 한 번 분량을 기다려 그런 세그먼트가 전부 소멸하기를 보장하는 것입니다.

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글