두 번째 인사만으로는 서버가 보낸 시작 번호가 상대에게 닿았는지 알 수 없어요. 세 번째 ACK이 와야 양쪽의 시작 번호가 모두 확인돼요.
03 · 연결 준비 확인
두 컴퓨터는 세 번 인사한 뒤 대화합니다.
전화의 “여보세요? — 네, 들려요 — 저도 들려요”와 같습니다. 어려운 번호는 접어두고 세 문장만 따라가 보세요.
마지막 확인
아래 파란 버튼만 누르세요
세 문장만 주고받으면 연결돼요
- 1시작 요청
- 2서버 응답
- 3마지막 확인
- 4연결 완료
‘첫 인사 보내기’를 누르면 세 번의 인사와 연결 완료를 차례로 보여드려요.
이유 세 가지만
왜 두 번이 아니라 세 번일까요?
서로의 SEQ를 알아두면 데이터가 여러 조각으로 잘리고 뒤섞여 도착해도 순서대로 복원할 수 있어요.
일반적인 응용 데이터는 연결이 확인된 뒤 프로그램에 전달돼요. 오래된 중복 연결 요청을 새 연결로 착각할 가능성도 줄여요.
이 데모에 대하여
여덟 단계로 쪼갠 연결 수립 과정
화면에서 넘기는 네 장면은 사실 여덟 단계짜리 상태 머신의 일부만 보여준 것입니다. 세그먼트가 만들어지는 단계, 회선 위를 이동하는 단계, 상대가 받아 처리하는 단계가 각각 따로 있고, 그 여덟 개가 미리 계산돼 배열로 들어 있습니다. 버튼은 그 배열의 인덱스를 옮기는 일만 하고, 되돌리기를 눌러도 계산이 다시 일어나지 않습니다. 애니메이션처럼 보이지만 시간에 따라 흘러가는 것이 아니라, 언제든 앞뒤로 오갈 수 있는 정지된 장면들입니다.
- ‘첫 인사 보내기’를 눌러 SYN 이 만들어지고 회선을 건너는 두 단계를 봅니다.
- 서버 쪽 상태 배지가 LISTEN 에서 SYN_RCVD 로 바뀌는 순간을 확인합니다.
- 말풍선의 ‘SEQ·ACK 번호 보기’를 펼쳐 100 · 101 · 300 · 301 이 어디서 나왔는지 봅니다.
- 다섯 번째 단계에서 내 쪽만 먼저 ESTABLISHED 가 되는 것을 확인합니다.
- 마지막 장면에서 양쪽이 모두 ESTABLISHED 로 맞춰지는지 봅니다.
- ‘처음부터’를 누르고, 이번에는 상태 배지만 보면서 다시 넘겨 봅니다.
- 마지막으로 회선 위에 세그먼트가 떠 있는 단계가 몇 개인지 세어 봅니다. 세 번입니다.
- 서버 쪽이 먼저 연결됐다고 판단하는 시점이 언제인지 되짚어 봅니다.
- 양쪽 상태가 서로 다른 구간이 몇 단계 동안 이어지는지 세어 봅니다.
이 화면이 규격에서 가져온 것
01
양쪽 상태를 따로 들고 있습니다.
각 단계는 내 쪽 상태와 서버 쪽 상태를 각각 하나씩 가지고 있습니다. 연결이 하나의 값으로 관리되는 것이 아니라 양 끝이 각자의 상태를 들고 있다는 점이 중요한데, 그래서 다섯 번째 단계처럼 한쪽은 연결됐다고 보는데 다른 쪽은 아직 아닌 구간이 생깁니다. 실무에서 마주치는 여러 증상이 바로 이 어긋난 구간에서 나옵니다.
02
회선 위의 단계를 따로 뒀습니다.
세그먼트를 만드는 단계와 그것이 상대에게 도착하는 단계 사이에 ‘이동 중’ 단계를 하나 끼워 넣었습니다. 두 단계로 나누지 않으면 보내는 즉시 받는 것처럼 보여서, 왜 세 번이나 오가야 하는지가 설명되지 않기 때문입니다. 첫 SYN 이 상대에게 닿았는지 보낸 쪽이 알 수 없다는 사실이 이 데모 전체의 전제입니다.
03
ACK 은 다음에 받고 싶은 번호입니다.
받은 번호가 아니라 다음에 기대하는 번호를 적는다는 점이 처음 볼 때 가장 헷갈리는 부분입니다. SYN 은 데이터가 없는데도 번호를 하나 차지하기 때문에 100 에 대한 응답이 101 이 됩니다. 화면의 각 필드에 붙은 설명이 이 계산을 그때그때 짚어 주도록 해 두었고, 숫자를 외우는 대신 규칙을 확인하게 하는 것이 목적입니다.
04
시작 번호는 읽기 쉬운 값으로 고정했습니다.
화면의 100 과 300 은 규격이 정한 값이 아니라 데모가 고른 예시입니다. 실제 시작 번호는 공격자가 다음 값을 추측해 남의 연결에 끼어들지 못하도록 예측하기 어렵게 선택합니다. 여기서 고정값을 쓴 것은 101 과 301 이 어디서 나왔는지 눈으로 따라갈 수 있게 하기 위해서이고, 이 점을 각 필드 설명에도 함께 적어 두었습니다.
05
상태 이름은 규격의 것을 그대로 씁니다.
CLOSED · LISTEN · SYN_SENT · SYN_RCVD · ESTABLISHED 는 데모가 지어낸 이름이 아니라 규격에 정의된 상태입니다. 한글 설명을 함께 붙이되 영문 이름을 그대로 노출한 이유는, 실제로 서버에서 연결 상태를 확인할 때 보게 되는 문자열이 이것들이기 때문입니다. 화면에서 익힌 단어가 터미널에서 그대로 쓰이는 편이 낫습니다.
06
계산과 화면을 분리해 두었습니다.
여덟 단계를 만드는 코드는 화면 코드와 따로 있고, 자동 테스트가 단계 수와 각 단계의 상태 조합을 직접 확인합니다. 버튼을 눌러 가며 사람이 확인하는 방식이었다면 단계를 하나 고칠 때마다 전부 다시 봐야 했을 텐데, 상태 머신만 따로 검증하면 화면을 바꿔도 연결 절차가 조용히 틀어지지 않습니다.
07
멈춘 칸이 곧 볼 곳을 정해 줍니다.
이 표를 실무에서 쓸 수 있는 이유는, 연결이 안 될 때 어느 상태에서 멈췄는지가 원인의 범위를 좁혀 주기 때문입니다. 내 쪽이 첫 인사를 보낸 상태에서 움직이지 않으면 그 인사가 상대에게 닿지 않은 것이고, 서버 쪽에 답을 보낸 상태가 잔뜩 쌓여 있으면 서버는 답했는데 마지막 확인이 돌아오지 않는 것입니다. 화면에서 상태 배지를 크게 띄워 둔 것도 숫자보다 이 칸을 먼저 보는 습관을 들이려는 의도입니다.
08
네 장면은 여덟 단계에서 골라낸 것입니다.
화면 위쪽의 장면 표시는 네 칸이지만 내부 단계는 여덟 개입니다. 세그먼트가 만들어지는 순간과 도착하는 순간 중 사람이 이야기로 기억하기 좋은 지점만 골라 장면으로 묶었기 때문입니다. 모든 단계를 다 보여주면 정확하지만 여덟 번을 눌러야 하고, 네 번으로 줄이면 대신 회선 위에 머무는 구간이 흐려집니다. 두 표현을 한 화면에 같이 둔 것이 절충안입니다.
연결을 여는 절차만 다룹니다.
이 화면은 실제 패킷을 잡아 보여주는 것이 아니라 규격의 절차를 따라 만든 교육용 시뮬레이션입니다. 네트워크에 아무것도 보내지 않고 브라우저 안에서만 돌아갑니다. 다루는 범위는 연결을 여는 세 번의 인사까지이고, 연결을 닫는 절차, 재전송과 타임아웃, 첫 패킷에 데이터를 실어 보내는 최적화, 그 위에 올라가는 암호화 절차는 모두 빠져 있습니다. 창 크기 조절이나 혼잡 제어처럼 연결이 열린 뒤에 동작하는 것들도 여기서는 보이지 않습니다. 연결이 안 될 때의 진단은 이 화면만으로 끝나지 않고, 어느 상태에서 멈췄는지를 실제 서버에서 확인해야 합니다.
참고 자료RFC 9293 — Transport Control Protocol ↗RFC 6298 — 재전송 타이머 계산 ↗
실험을 마쳤다면