합동회사 코무라소프트
3장

시퀀스 번호와 재전송 — TCP 는 도착했음을 어떻게 확인하는가

바이트 하나하나에 번호를 매기고, ack 번호 = 다음에 원하는 바이트로 답을 맞춘다. 도착하지 않았을 때의 2 가지 알아채는 방법 — 재전송 타이머와 중복 ACK — 를 구별한다.

「도착했을 것」을 어떻게 확인하는가

제 1 장에서 본 대로, IP 는 잃어버린 것을 알려 주지 않습니다. 그런데도 TCP 는 「반드시 도착한다, 도착하지 않으면 알아챈다」를 약속합니다. 장치는 매우 소박해서, 택배의 송장 번호와 수령 사인과 닮았습니다.

번호를 매긴다(seq)
보내는 바이트 하나하나에 일련번호를 매긴다. 세그먼트의 헤더에는 선두 바이트의 번호를 쓴다
수령을 돌려준다(ack)
수신 측은 「다음에 원하는 바이트의 번호」를 돌려준다. ack = 1501 은 「1500 까지는 빠짐없이 받았다」는 의미
돌아오지 않으면 다시 보낸다
일정 시간 ACK 가 없으면 잃어버렸다고 간주하고 재전송한다. 몇 번 도착해도 번호로 중복을 알아챌 수 있다

중요한 것은, 번호가 패킷마다가 아니라 바이트마다 매겨져 있다는 점입니다. TCP 에게 데이터는 「바이트의 흐름」이며, 세그먼트(패킷에 실리는 단위)는 그 흐름을 편의상 자른 조각에 지나지 않습니다. 세기 시작하는 번호를 앞 장의 핸드셰이크에서 합의했으므로, 양쪽은 처음부터 같은 잣대로 바이트를 셀 수 있습니다. 이후의 예에서는 읽기 쉽도록 세기 시작을 1000 으로 하고, 최초의 데이터 바이트를 1001 로 합니다.

연속하는 바이트열에 일련번호가 매겨지고, 세그먼트가 그 범위를 잘라내어 운반하며, 수신 측이 다음에 원하는 바이트의 번호를 ack 로 돌려주는 모습의 그림

seq = 1001 로 500 바이트의 세그먼트는 바이트 1001〜1500 을 운반하고, ACK 는 「다음에 원하는」 1501 을 가리킵니다. 번호의 주역은 세그먼트가 아니라 바이트입니다.

ack 번호 = 다음에 원하는 바이트의 번호

캡처를 읽는 데 있어 가장 큰 급소가 ack 번호의 해석입니다. 「어디까지 받았는가」가 아니라 「다음에 어디부터 원하는가」를 가리킵니다. seq = 1001 부터 500 바이트를 받았다면, 도착한 마지막 바이트는 1001 + 500 − 1 = 1500 번. 그래서 돌려주는 ack 는 1501 입니다.

또 하나의 급소가 누적 확인 응답이라는 성질입니다. ACK 는 「여기까지는 빠짐없이 연속으로 받았다」는 것밖에 표현할 수 없습니다. 중간의 3001〜4000 이 빠진 채 4001〜5000 이 도착해도, 돌려줄 수 있는 ack 는 3001 그대로. 도착한 분량은 수신 버퍼에 보관해 두고, 구멍이 메워진 순간 ack 는 단숨에 5001 까지 뜁니다. 이 「보관해서 다시 정렬하는」 움직임이야말로 약속 그 2, 「순서대로」의 실체입니다.

소문제 3-1 — seq 와 ack 를 손으로 계산한다

캡처를 읽는 힘은 이 계산이 모든 것의 토대입니다. 바이트의 범위를 종이에 써서 확인해 주세요.

Q1. 송신 측이 seq = 1001 의 세그먼트로 500 바이트의 데이터를 보냈습니다. 수신 측이 이것을 받고 돌려주는 ack 번호는 얼마입니까.

Q2. 수신 측은 바이트 3000 까지 연속으로 수신 완료했습니다. 거기에 중간의 3001〜4000 을 건너뛰고 4001〜5000 의 세그먼트가 도착했습니다. 수신 측이 돌려주는 ack 번호는 얼마입니까.

Q3. TCP 의 시퀀스 번호가 「세그먼트(패킷)마다」가 아니라 「바이트마다」 매겨져 있는 것의 이점은 어느 것입니까.

알아채는 방법 1 — 침묵(재전송 타이머)

ACK 가 돌아오지 않을 때, 얼마나 기다리면 「잃어버렸다」고 판단해도 될까요. 너무 짧으면 낭비되는 재전송으로 네트워크를 압박하고, 너무 길면 사용자를 기다리게 합니다. TCP 는 보낼 때마다 왕복 시간(RTT: 보내고 나서 ACK 가 돌아올 때까지의 시간)을 계속 측정하고, 그 평균과 편차로부터 재전송 타임아웃(RTO)을 동적으로 계산합니다. 같은 건물 안이라면 몇 밀리초, 대륙 간이라면 수백 밀리초 — 회선에 맞춰 잣대가 바뀌는 것입니다.

RTO 가 만료되면 빠진 세그먼트를 재전송하고, RTO 를 배로 늘려서 다음을 기다립니다(지수 백오프). ACK 가 돌아오지 않는 가장 유력한 원인은 혼잡이므로, 다시 보낼수록 간격을 벌려서, 혼잡에 몰아치기를 피하는 설계입니다.

알아채는 방법 2 — 비명(중복 ACK)과 빠른 재전송

침묵을 기다리는 것보다 빠른 방법이 있습니다. 바이트 8000 까지 도착한 후에 8001〜9000 이 손실되고, 그 후속만 계속 도착하면, 수신 측은 도착할 때마다 ack = 8001 을 돌려줄 수밖에 없습니다. 송신 측에서 보면 같은 번호의 ACK 가 반복해서 도착한다 — 이것이 중복 ACK 입니다.

중복 ACK 는 1 통마다 「후속은 도착했는데, 8001 부터의 구멍이 메워지지 않는다」고 말하고 있습니다. 같은 것이 3 회 도착하면, 송신 측은 더 이상 기다리지 않습니다. 후속이 도착하고 있다 = 경로는 살아 있다 = 빠진 것은 아마 1 개라고 추리하고, RTO 를 기다리지 않고 seq = 8001 의 세그먼트만을 재전송합니다. 이것이 빠른 재전송입니다.

캡처에서 재전송을 발견하면, 어느 쪽의 재전송인지를 봐 주세요. 중복 ACK 유래라면 가벼운 단발 로스, 타임아웃 유래라면 응답이 전혀 돌아오지 않는 심각한 상태 — 같은 「재전송」이라도 해석은 정반대입니다.

소문제 3-2 — 도착하지 않았음을 어떻게 알아채는가

TCP 에는 「도착하지 않았다」를 알리는 통지가 없습니다. 침묵과 중복이라는 2 가지 간접 증거로 추리합니다.

Q4. 재전송 타이머(RTO)의 설명으로 올바른 것은 어느 것입니까.

Q5. 송신 측에 같은 ack 번호의 ACK(중복 ACK)가 몇 번이나 도착하는 일이 있습니다. 수신 측에서 무엇이 일어나고 있습니까.

Q6. 같은 중복 ACK 가 3 회 도착한 시점에서, 송신 측은 타임아웃을 기다리지 않고 빠진 세그먼트를 재전송합니다(빠른 재전송). 타임아웃을 기다리지 않고 보내도 좋다고 판단할 수 있는 근거는 어느 것입니까.

이 장에서 가져갈 것

  • 번호는 바이트마다. seq = 1001 의 500 바이트는 바이트 1001〜1500 을 운반한다
  • ack 번호 = 다음에 원하는 바이트의 번호. 게다가 누적 확인 응답 — 구멍보다 앞으로는 나아갈 수 없다
  • 로스를 알아채는 방법은 2 가지. 침묵(RTO 만료, 지수 백오프)비명(중복 ACK 3 회 → 빠른 재전송)
  • 중복 ACK 유래의 재전송은 경증, 타임아웃 유래의 재전송은 중증의 신호

여기까지로 「반드시 도착한다·순서대로」의 구조가 갖춰졌습니다. 다음 장은 약속 그 3 의 전반 — 상대의 사정에 맞추는 슬라이딩 윈도우입니다. ACK 에 합승해 오는 「앞으로 몇 바이트 받을 수 있는가」라는 숫자가 주역이 됩니다.