← 아티클 목록

tcp 3 way handshake — 연결은 어떻게 맺어지는가

2028-10-02#networking#tcp#handshake

"TCP는 연결을 맺고 통신한다"는 말은 들었지만, 그 '연결'이 정확히 무엇인지는 흐릿합니다. TCP 연결은 물리적인 선이 아니라 양쪽이 서로 준비됐음을 확인한 합의 상태이고, 그 합의를 만드는 절차가 3-way handshake입니다.

핵심: 세 번 주고받는 이유

연결을 맺으려면 양쪽이 "보낼 준비 됐다"와 "받을 준비 됐다"를 서로 확인해야 합니다. 한 번이나 두 번으로는 한쪽의 수신 능력을 보장할 수 없어, 최소 세 번의 교환이 필요합니다.

단계방향플래그의미
1클라이언트 → 서버SYN"연결하고 싶다. 내 순서번호는 x"
2서버 → 클라이언트SYN-ACK"좋다(ACK x+1). 내 순서번호는 y"
3클라이언트 → 서버ACK"확인했다(ACK y+1). 시작하자"

1단계에서 클라이언트가 SYN을 보내 연결 의사와 순서번호를 알립니다. 2단계에서 서버가 그걸 받았다는 ACK와 자기 SYN을 함께 보냅니다(그래서 SYN-ACK). 3단계에서 클라이언트가 서버의 SYN까지 확인하는 ACK를 보내면, 양쪽 모두 상대의 송수신 능력을 확인한 셈이라 연결이 성립합니다.

왜 두 번으로는 안 되나

두 번만 주고받으면 서버는 클라이언트가 자기 응답(SYN-ACK)을 받았는지 알 수 없습니다. 세 번째 ACK가 있어야 비로소 "내 패킷도 상대에게 도달했다"가 양방향으로 확인됩니다. 이 합의된 순서번호(x, y)는 이후 데이터의 순서를 맞추고 빠진 패킷을 재전송하는 기준이 됩니다. 연결을 끊을 때는 비슷하게 FIN을 주고받는 4-way 과정을 거칩니다.

직접 확인하기

실제 SYN 패킷이 오가는 모습은 tcpdump로 잡아 볼 수 있습니다.

로컬 터미널
sudo tcpdump -i any 'tcp port 443' -n
OUTPUT
IP 10.0.0.5.51234 > 93.184.216.34.443: Flags [S], seq 1000
IP 93.184.216.34.443 > 10.0.0.5.51234: Flags [S.], seq 8000, ack 1001
IP 10.0.0.5.51234 > 93.184.216.34.443: Flags [.], ack 8001

Flags [S]가 SYN, [S.]가 SYN-ACK, [.]가 ACK입니다. ack 1001이 클라이언트 seq 1000에 1을 더한 값인 점, ack 8001이 서버 seq 8000에 1을 더한 값인 점이 표의 x+1·y+1과 정확히 맞아떨어집니다. 연결이 맺어진 뒤 상태는 ss -tESTAB으로도 볼 수 있습니다.

요점 정리

  • TCP 연결은 선이 아니라 양방향 준비 확인이라는 합의 상태.
  • SYN → SYN-ACK → ACK 세 단계로 양쪽의 송수신 능력을 서로 확인.
  • 두 번으로는 한쪽의 수신 확인이 빠져 세 번이 필요.
  • tcpdump[S]·[S.]·[.] 플래그로 핸드셰이크를 직접 관찰하세요.

TCP 핸드셰이크와 패킷을 직접 캡처해 분석하는 실습은 네트워크 트랙에서 회원가입 없이 무료로 익힐 수 있습니다.