CS/Computer Network

[컴퓨터네트워크/Computer Network] 신뢰적인 데이터 전송 원리 완벽 정리 (rdt 3.0)

binaryroot 2026. 5. 23. 14:27
728x90
728x90

앞서 rdt 1.0부터 2.2까지, 비트 에러(Bit Errors)가 발생하는 환경에서 데이터를 안전하게 주고받는 방법에  대해 공부했었다. 이번에는 rdt 3.0, 즉 네트워크의 또 다른 골칫거리인 '패킷 유실(Packet Loss)'까지 해결하는 과정에 대해 정리하고자 한다.

 

앞선 프로토콜들(rdt 2.x)에서는 채널에 비트 에러는 있지만, 패킷이 아예 사라지는 경우는 없다고 가정했다. 하지만 현실의 네트워크는 패킷을 중간에 잃어버리기도 하고, ACK 응답 자체가 소멸하기도 한다. 이를 해결하기 위해 등장한 것이 바로 rdt 3.0이다.

1. 패킷 유실(Packet Loss)의 문제와 해결책

송신자가 데이터를 보냈는데 패킷이 네트워크에서 사라지거나, 수신자가 보낸 ACK가 사라지면 어떻게 될까? 송신자는 수신자가 데이터를 잘 받았는지 알 방법이 없으니 무한정 기다리게 된다. 이를 해결하기 위해 Timer(타이머) 개념을 도입할 수 있다.

핵심 메커니즘: Countdown Timer

  • 작동 원리: 송신자는 패킷을 보낼 때마다 타이머를 시작한다.
  • Timeout(타임아웃): 만약 타이머 시간이 다 될 때까지 ACK를 받지 못하면, 송신자는 "패킷이나 ACK 중 하나가 유실되었구나!"라고 판단하고 해당 패킷을 다시 retransmit(재전송)한다.

2. rdt 3.0: Sender와 동작 시나리오 (In Action)

rdt 3.0은 '패킷 유실(Packet Loss)'이라는 난제를 해결하기 위해 타이머를 도입한다. 송신자는 타이머를 통해 응답을 기다리는 시간을 관리한다.

  • 정상적인 경우: 송신 후 타이머가 만료되기 전에 ACK가 잘 도착한다.
  • 패킷 유실: 데이터 패킷이 사라지면, 타이머가 만료될 때까지 응답이 없다. 이때 송신자는 재전송.
  • ACK 유실: 데이터는 잘 전달되었지만 돌아오는 ACK가 사라진다. 송신자는 응답이 없으므로 다시 재전송. 이때 수신자는 중복 패킷임을 알아차리고 다시 ACK를 보낸다.. (이것이 rdt 3.0이 올바르게 동작하는 핵심이다.)
  • 조기 타임아웃(Premature timeout): 타이머 설정 시간이 너무 짧아 데이터가 도착하기도 전에 재전송이 일어나는 경우이다.

2.1 rdt 3.0 Sender FSM

rdt 3.0의 송신자는 패킷을 보낼 때마다 Start_timer를 호출한다. 이후 두 가지 상황이 발생 가능하다.

  1. ACK 수신: 타이머가 끝나기 전에 올바른 ACK가 오면 Stop_timer를 호출하고 다음 패킷을 보낼 준비를 한다.
  2. Timeout: 타이머 시간이 만료되면, 송신자는 패킷이 유실되었거나 응답이 유실되었다고 판단하여 해당 패킷을 retransmit(재전송)하고 타이머를 다시 시작한다.

rdt3.0 sender

2.2 rdt 3.0 in Action (다양한 시나리오)

채널의 비신뢰적 환경에 따라 다음과 같은 상황들이 발생한다.

  • 상황 1: 패킷 또는 ACK 유실(Loss)
    • 송신자가 패킷을 보냈으나, 수신자에게 도달하지 못하거나 혹은 수신자가 보낸 ACK가 돌아오지 않는 경우이다. 이 경우 송신자의 타이머가 만료되며, 송신자는 패킷을 재전송한다. 수신자는 이미 번호가 붙은 패킷을 받고 있으므로, 재전송된 패킷을 구별하여 중복 처리를 방지한다.
  • 상황 2: 조기 타임아웃(Premature timeout)
    • 네트워크의 지연(Delay)이 길어 실제 패킷은 잘 도착했음에도 타이머가 먼저 만료되는 경우이다. 송신자는 패킷을 재전송하게 되고, 수신자는 같은 번호의 패킷을 또 받게 되지만, 이미 처리한 패킷임을 알고 ACK만 다시 보낸다. 신뢰성은 유지되지만 네트워크 효율은 떨어지게 된다.

no loss & packet loss
ACK loss and premature timeout/delayed ACK

3. rdt 3.0의 성능 한계 (Stop-and-Wait의 비효율성)

rdt 3.0의 가장 큰 문제점은 Stop-and-Wait(전송 후 대기) 방식의 비효율성이다. 송신자는 하나의 패킷을 보내고 ACK를 받을 때까지 모든 행동을 멈추고 기다려야 한다.

 

rdt3.0 : stop-and-wait operation

왜 비효율적인가?

만약 네트워크의 대역폭(Bandwidth)은 넓은데, 송신자와 수신자 사이의 왕복 시간(RTT, Round Trip Time)이 매우 길다면 어떻게 될까? 송신자가 실제 데이터를 보내는 시간보다 기다리는 시간이 압도적으로 길어지게 된다.

이를 Utilization(이용률, U_sender) 공식으로 표현하면 다음과 같다.

 

이 수치를 보면 네트워크 자원을 매우 낭비하고 있다는 것을 알 수 있다. 그래서 실제 TCP와 같은 프로토콜에서는 한 번에 여러 패킷을 보내는 Pipelining(파이프라이닝) 기술을 사용하게 된다.

 

지금까지 우리는 rdt 1.0(완벽한 채널)에서 시작해, rdt 2.x(비트 에러 해결)를 거쳐 rdt 3.0(패킷 유실 해결)까지 알아보았다.

이 과정에서 우리는 세 가지를 정확하게 이해할 수 있었다.

  1. Checksum: 데이터가 깨졌는지 확인한다.
  2. Sequence Number: 패킷의 순서를 식별하고 중복을 걸러낸다.
  3. Timer: 패킷 유실 시 재전송을 통해 신뢰성을 확보한다.

하지만 Stop-and-Wait의 한계로 인해 '한 번에 하나씩'이 아닌 '한 번에 여러 개를 효율적으로 보내는 방법(Pipelining)'에 대해 고민해보는 것이 필요하다.

다음 글에서는 Pipelining과 실제 네트워크의 핵심인 TCP에 대해 더 알아보고 정리하도록 하겠다.

728x90