TCP 연결 수립에서 SYN과 ACK가 오가는 방식
TCP 연결 수립 과정에서 SYN, SYN+ACK, ACK가 수행하는 역할과 시퀀스 번호, 상태 전이, 손실 대응 및 연결 재사용 관점을 정리한다.
2026-08-14 · 최초 발행 2025-07-16
TCP가 데이터를 보내기 전에 확인하는 것
TCP는 연결 지향적(Connection-Oriented) 프로토콜이다. 데이터를 전송하기 전 양측 사이에 논리적 연결을 만들고, 그 위에서 순서 보장, 흐름 제어, 오류 복구를 수행할 수 있는 상태를 마련한다.
이 연결 수립 절차가 3-Way Handshaking이다. 클라이언트와 서버는 세 번의 패킷 교환으로 서로 데이터를 주고받을 준비가 되었음을 확인하고, 초기 시퀀스 번호(ISN: Initial Sequence Number)를 교환한다.
SYN부터 ACK까지 이어지는 연결 수립
클라이언트는 먼저 서버로 SYN 패킷을 보내 연결을 요청한다. 이때 시퀀스 번호를 초기화하며, 예시에서는 seq=100이고 SYN 플래그는 1이다.
서버는 요청을 받으면 SYN+ACK 패킷으로 응답한다. 서버 역시 시퀀스 번호를 초기화하고(seq=2000), 클라이언트 시퀀스 번호에 1을 더한 값으로 확인 응답 번호를 설정한다(ack=101). SYN과 ACK 플래그는 모두 1이다.
마지막으로 클라이언트가 ACK를 전송한다. 클라이언트의 시퀀스 번호는 받은 확인 응답 번호(seq=101)가 되고, 서버 시퀀스 번호에 1을 더한 값을 확인 응답 번호로 보낸다(ack=2001). 이 ACK까지 도착하면 양방향 데이터 전송 채널이 수립된다.
시퀀스 번호가 연결의 기준점을 만든다
시퀀스 번호는 각 호스트가 생성하는 초기 시퀀스 번호에서 시작한다. 랜덤하게 생성되어 보안을 강화하며, 이후 데이터 바이트 스트림에서 현재 위치를 식별하는 기준이 된다.
확인 응답 번호는 상대방으로부터 다음에 수신하기를 기대하는 시퀀스 번호다. 수신 측이 어디까지 데이터를 받았는지 알리는 역할을 하며, 일반적으로 상대방 시퀀스 번호에 1을 더한 값으로 설정된다.
Wireshark 같은 패킷 분석 도구에서는 다음과 같이 연결 수립 패킷을 확인할 수 있다.
Frame 1: Client -> Server (SYN)
Source Port: 54321
Destination Port: 80 (HTTP)
Sequence Number: 100
Flags: SYN
Frame 2: Server -> Client (SYN, ACK)
Source Port: 80
Destination Port: 54321
Sequence Number: 2000
Acknowledgment Number: 101
Flags: SYN, ACK
Frame 3: Client -> Server (ACK)
Source Port: 54321
Destination Port: 80
Sequence Number: 101
Acknowledgment Number: 2001
Flags: ACK
연결 수립 중 양측이 바꾸는 상태
클라이언트는 CLOSED 상태에서 SYN을 보낸 뒤 SYN_SENT로 이동한다. SYN+ACK를 받고 ACK를 전송하면 ESTABLISHED 상태가 된다.
서버는 CLOSED에서 LISTEN 상태로 연결을 기다린다. SYN을 수신하면 SYN_RECEIVED로 바뀌고 SYN+ACK를 보낸다. 클라이언트의 ACK를 받으면 ESTABLISHED 상태가 된다.
연결이 만들어지면 양방향 통신 가능성을 확인할 수 있고, 패킷 손실·중복·순서 오류에 대응할 기반이 생긴다. 초기 시퀀스 번호와 윈도우 크기 등 TCP 옵션도 이 과정에서 교환한다. 또한 서버와 클라이언트는 연결 관리에 필요한 상태 정보를 동기화한다.
웹 요청과 연결 종료까지의 흐름
웹 브라우저가 www.example.com의 80번 포트에 요청을 보낼 때도 먼저 TCP 연결을 시도한다. Handshaking으로 연결을 수립한 뒤 HTTP GET 요청을 보내고, 서버는 HTTP 응답을 전송한다. 연결 종료에는 FIN → ACK → FIN → ACK 순서의 4-Way Handshaking이 사용되며, 양방향 연결의 각 방향을 독립적으로 종료한다.
패킷이 유실될 때와 SYN Flooding
SYN 패킷이 사라지면 클라이언트는 타임아웃 뒤 SYN을 재전송하며, 일반적으로 3~5회 재시도한다. SYN+ACK가 유실된 경우 서버는 SYN_RECEIVED 상태에서 대기하고, 클라이언트가 타임아웃 후 SYN을 다시 보내면 서버도 SYN+ACK를 재전송한다.
마지막 ACK가 손실되면 서버는 SYN_RECEIVED 상태에서 타임아웃을 기다린다. 데이터 전송이 시작되면 ACK가 포함되어 연결이 확립된다.
SYN Flooding은 대량의 SYN 패킷으로 서버 자원을 고갈시키려는 공격이다. SYN Cookie와 백로그 큐 관리는 이에 대응하는 방법이다.
연결 수립 비용을 줄이는 선택지
TCP Fast Open(TFO)은 재연결 시 SYN 패킷에 데이터를 포함할 수 있게 한다. 첫 RTT(Round Trip Time)에서 데이터 전송이 가능해져 웹 페이지 로딩 시간을 줄일 수 있다.
이미 수립한 TCP 연결을 재사용하는 방법도 있다. HTTP/1.1의 Keep-Alive와 HTTP/2의 멀티플렉싱은 연결 수립 오버헤드를 줄이는 데 사용된다.
소켓 프로그래밍에서는 클라이언트가 connect()를 호출할 때 이 연결 수립이 수행되고, 서버는 accept()에서 클라이언트 연결을 수락한다. 연결 타임아웃과 재시도 메커니즘을 설계하고, 불필요한 연결을 줄이며 연결 풀링(Connection Pooling)을 검토할 필요가 있다.