reliable data transfer

Tasker_Jang·2026년 9월 22일
post-thumbnail

1. 아래 계층이 해주지 않는 것

network 계층은 best effort입니다. 큐가 넘치면 패킷을 버리고, 전송 중에는 비트가 뒤집힐 수도 있습니다. 그런데 애플리케이션은 TCP 소켓에 쓴 바이트가 그대로, 빠짐없이, 순서대로 도착하길 기대합니다.

reliable data transfer protocol(신뢰적 데이터 전송 프로토콜, rdt)은 이 간극을 메우는 원리입니다. 이를 한 번에 설계하지 않고, 채널의 결함을 하나씩 추가하면서 그때마다 필요한 장치를 하나씩 붙여 갑니다. 이 순서를 따라가면 TCP 헤더의 필드들이 왜 거기 있는지가 자연스럽게 설명됩니다.

2. rdt 1.0: 완벽한 채널

아래 채널이 비트 오류도 손실도 없는 완벽한 상태라고 가정한 출발점입니다. 송신 측은 데이터를 보내고 수신 측은 받으면 끝입니다. 할 일이 없다는 것 자체가 요점입니다. 이후 모든 장치는 이 가정이 깨질 때마다 추가됩니다.

3. rdt 2.0: 비트 오류와 피드백

이제 채널이 비트를 뒤집을 수 있습니다. 필요한 장치는 셋입니다.

  • error detection(오류 검출): checksum으로 깨졌는지 확인
  • feedback(피드백): 수신 측이 결과를 알려줌. 잘 받았으면 ACK(acknowledgement, 긍정 확인응답), 깨졌으면 NAK(negative acknowledgement, 부정 확인응답)
  • retransmission(재전송): NAK를 받으면 다시 보냄

송신 측은 패킷 하나를 보낸 뒤 응답이 올 때까지 기다리므로 stop-and-wait 방식입니다.

그런데 rdt 2.0은 치명적 결함이 있습니다. ACK나 NAK 자체가 깨지면 송신 측은 수신 측에서 무슨 일이 있었는지 알 수 없습니다. 안전하게 다시 보내면 되지 않을까 싶지만, 원래 패킷이 잘 도착했었다면 수신 측은 같은 데이터를 두 번 받게 됩니다. 문제는 수신 측이 이것이 재전송인지 새 데이터인지 구분할 수 없다는 점입니다.

4. sequence number: 0과 1이면 충분하다

송신자와 수신자가 서로 무엇을 말하고 있는지 명확히 하기 위해 sequence number(순서 번호)를 붙입니다. 송신 측은 ACK/NAK가 깨지면 일단 재전송하고, 수신 측은 번호를 보고 중복이면 버립니다. 교재에서는 이 단계를 rdt 2.1이라 부릅니다.

stop-and-wait에서는 한 번에 패킷 하나만 오가므로, 번호는 0과 1 두 개면 충분합니다. 재전송이면 같은 번호를 쓰고 새 패킷이면 번호를 뒤집으면 되기 때문입니다. 수신 측은 "지금은 0을 기다리는 중"이라는 상태만 기억하면 됩니다.

5. rdt 2.2: NAK 없이도 된다

NAK를 없앨 수 있습니다. 수신 측이 NAK 대신 마지막으로 제대로 받은 패킷에 대한 ACK를 보내는 것입니다. 송신 측이 같은 패킷에 대한 ACK를 두 번 받으면, 그다음 패킷이 제대로 도착하지 않았다는 뜻이 됩니다. 이를 위해 ACK에도 어떤 패킷을 확인하는지 sequence number가 들어가야 합니다.

메시지 종류가 하나 줄었지만 표현력은 같습니다. duplicate ACK(중복 ACK)가 곧 NAK 역할을 합니다. TCP가 이 방식을 씁니다.

6. rdt 3.0: 손실까지 있는 채널, 그리고 timer

마지막으로 채널이 패킷을 통째로 잃어버릴 수 있다고 가정합니다. 데이터든 ACK든 사라지면 송신 측은 영원히 응답을 기다리게 됩니다. 지금까지의 장치로는 "아무 일도 일어나지 않음"을 감지할 수 없습니다.

해법은 timer(타이머)입니다. 송신 측은 보낼 때 타이머를 켜고, 적당한 시간 안에 ACK가 오지 않으면 잃어버렸다고 보고 재전송합니다.

타이머가 너무 짧아 패킷이 단지 늦게 왔을 뿐인데 재전송하는 경우도 생깁니다. 그래도 문제없습니다. 중복은 sequence number가 이미 걸러주기 때문입니다. 번호가 0과 1을 번갈아 쓰므로 rdt 3.0을 alternating bit protocol이라고도 부릅니다. 이것이 강의의 최종 프로토콜입니다. 다만 여전히 한 번에 하나씩만 보내므로 느리다는 숙제가 남습니다.

7. 한눈에 보는 rdt의 진화

버전채널 가정추가된 장치남는 문제
rdt 1.0완벽없음-
rdt 2.0비트 오류checksum, ACK/NAK, 재전송ACK/NAK가 깨지면 중복 발생
rdt 2.1비트 오류sequence number (0, 1)메시지 종류가 셋
rdt 2.2비트 오류ACK에 번호, duplicate ACK로 NAK 대체손실 대응 불가
rdt 3.0비트 오류 + 손실timer한 번에 하나씩만 전송

8. TCP 헤더: rdt의 장치들이 있는 곳

위의 장치들이 실제 TCP 헤더에 어떻게 자리 잡았는지 보면 원리와 구현이 이어집니다. 중요한 것만 고릅니다.

필드크기rdt와의 연결
source / dest port각 16bitdemultiplexing
sequence number32bit4절의 번호. 단, 패킷이 아니라 바이트 단위로 셈
acknowledgment number32bit5절의 번호 달린 ACK. 다음에 받을 바이트 번호
checksum16bit3절의 error detection
flags (ACK, SYN, FIN 등)각 1bitACK 필드가 유효한지, 연결 시작·종료 표시
window16bit수신 측이 받을 수 있는 양. 흐름 제어에 사용

0과 1 두 개면 충분했던 번호가 TCP에서 32비트로 커진 것은, TCP가 stop-and-wait이 아니라 여러 세그먼트를 연달아 보내기 때문입니다.

profile
ML Engineer 🧠 | AI 모델 개발과 최적화 경험을 기록하며 성장하는 개발자 🚀 The light that burns twice as bright burns half as long ✨

0개의 댓글