TCP Three-Way Handshake로 이해하는 연결 수립과 상태 전이
TCP Three-Way Handshake의 SYN, SYN-ACK, ACK 교환과 시퀀스 번호, 연결 상태 전이, 장애·보안 관점의 운영 포인트를 정리한다.
2026-08-14 · 최초 발행 2025-08-10
TCP 연결은 양쪽의 준비 상태를 확인한 뒤 시작된다
TCP는 연결 지향 프로토콜이다. 데이터를 전송하기 전 송신측과 수신측은 양방향 통신을 위한 논리적 연결을 먼저 설정해야 한다. 이때 TCP 헤더의 Flag 필드를 이용해 세그먼트를 세 차례 교환하는 절차가 Three-Way Handshake다.
이 교환은 단순한 연결 요청을 넘어 양쪽이 통신할 수 있는 상태인지 확인하고, 이후 전송할 데이터의 순서를 관리할 초기 번호를 맞추는 과정이다.
SYN부터 ACK까지 이어지는 연결 상태 전이
클라이언트는 먼저 서버에 SYN 세그먼트를 보내며 연결을 요청한다. SYN 비트를 1로 설정하고 초기 Sequence Number(ISN)를 담아 전송한 뒤, 클라이언트는 SYN_SENT 상태로 전환한다. 이 시점의 Ack Number는 의미가 없으므로 0으로 설정한다.
TCP 세그먼트:
- 출발지 포트: 12
- 목적지 포트: 34
- Sequence Number: 1200
- Acknowledgment Number: 0
- Flags: SYN=1, ACK=0
서버는 클라이언트의 SYN을 수신하면 자신의 ISN을 설정하고 SYN과 ACK를 함께 응답한다. Ack Number에는 클라이언트 Sequence Number에 1을 더한 1201을 넣으며, 서버 상태는 SYN_RECEIVED가 된다.
TCP 세그먼트:
- 출발지 포트: 34
- 목적지 포트: 12
- Sequence Number: 4800
- Acknowledgment Number: 1201 (클라이언트의 Seq + 1)
- Flags: SYN=1, ACK=1
마지막으로 클라이언트는 서버의 SYN-ACK를 확인하는 ACK를 보낸다. Sequence Number는 앞서 받은 Ack Number인 1201이 되고, 서버 Sequence Number에 1을 더한 4801을 Ack Number로 설정한다. 이 응답 뒤 클라이언트와 서버는 모두 ESTABLISHED 상태가 되어 데이터를 전송할 수 있다.
TCP 세그먼트:
- 출발지 포트: 12
- 목적지 포트: 34
- Sequence Number: 1201
- Acknowledgment Number: 4801 (서버의 Seq + 1)
- Flags: SYN=0, ACK=1
번호 교환이 데이터 순서를 보장하는 방식
Sequence Number는 송신측이 보내는 데이터의 순서를 나타낸다. 연결을 시작할 때는 임의의 ISN으로 시작하며, 이후에는 전송한 데이터 바이트 수만큼 증가한다.
Acknowledgment Number는 수신측이 다음에 받기를 기대하는 Sequence Number다. Handshake 단계에서는 상대방 Sequence Number에 1을 더한 값을 사용한다. 이 번호 교환이 연결 이후 데이터의 전달 순서와 수신 확인을 위한 기반이 된다.
패킷 캡처에서 확인할 흐름
Wireshark 같은 패킷 분석 도구로 웹 서버 접속 과정을 보면 SYN, SYN-ACK, ACK가 순서대로 나타난다.
-
클라이언트가 웹 서버로 보내는 SYN 패킷
Frame 1: 54 bytes on wire Transmission Control Protocol, Src Port: 59102, Dst Port: 80, Seq: 0, Len: 0 Flags: 0x002 (SYN) -
서버가 돌려보내는 SYN-ACK 패킷
Frame 2: 60 bytes on wire Transmission Control Protocol, Src Port: 80, Dst Port: 59102, Seq: 0, Ack: 1, Len: 0 Flags: 0x012 (SYN, ACK) -
클라이언트가 보내는 ACK 패킷
Frame 3: 54 bytes on wire Transmission Control Protocol, Src Port: 59102, Dst Port: 80, Seq: 1, Ack: 1, Len: 0 Flags: 0x010 (ACK)
연결 실패를 분석할 때는 어느 세그먼트까지 도달했는지부터 확인한다. 패킷 손실, 지연, 방화벽 설정 오류는 이 교환의 특정 지점에서 연결을 멈추게 할 수 있다.
신뢰성의 기반이면서 운영 비용이 되는 절차
Handshake를 통해 양쪽은 데이터 전송 전에 준비 상태를 확인한다. ISN을 교환함으로써 이후 데이터의 순차적 전송을 위한 기준도 마련한다. ISN을 무작위로 선택하는 방식은 TCP Sequence Prediction 공격 방지에 쓰이며, 연결 수립 단계는 SYN Flooding 같은 DoS 공격을 탐지하는 지점이기도 하다.
반면 연결 지향 통신에는 초기 연결 수립 오버헤드가 따른다. UDP와 비교하면 연결을 시작하는 데 시간이 필요하므로, 실시간성보다 신뢰성이 중요한 애플리케이션에 적합하다.
미완료 연결이 남기는 문제
SYN Flooding은 공격자가 다수의 SYN 패킷을 보내고 ACK를 보내지 않는 공격이다. 서버는 SYN_RECEIVED 상태의 연결을 다수 유지하게 되고 자원이 고갈될 수 있다. SYN 쿠키, 백로그 큐 증가, 방화벽 설정 등이 대응 방안으로 쓰인다.
연결 과정에서 네트워크 장애로 일부 패킷이 손실되면 Half-Open Connection이 생길 수 있다. 불완전한 연결이 일정 시간 유지되면 리소스가 낭비되므로, 타임아웃 메커니즘으로 일정 시간이 지난 연결을 해제한다.
종료는 FIN과 ACK를 분리해 교환한다
TCP 연결 수립에는 Three-Way Handshake를 사용하지만, 연결 종료에는 Four-Way Handshake가 사용된다.
운영 환경에서 보는 TCP 연결 수립
웹 서버에서는 동시 연결 수에 맞춰 백로그 큐를 설정하고, Keep-Alive로 불필요한 연결 수립 오버헤드를 줄일 수 있다. TIME_WAIT 소켓 관리도 리소스 최적화와 연결된다.
로드 밸런서는 TCP 연결 상태를 모니터링하고, 비정상적인 연결 패턴을 감지해 공격 방어에 활용할 수 있다. 클라이언트와 서버 사이의 연결 유지 정책 역시 이 상태 전이를 기준으로 설정한다.
네트워크 장애가 발생했을 때 Handshake의 각 단계를 따라가면 연결 실패 원인, 패킷 손실과 지연, 방화벽 설정 오류를 구분하는 데 도움이 된다.