Infra & Security Eng/Network & Security
rdt 3.0 완벽 정리: 타이머(Timer)를 활용한 패킷 유실 해결과 신뢰적 전송의 완성
by 엔지니어 E
2026. 2. 11.
[송신측] rdt 3.0: 유실에 대응하는 타이머 메커니즘
rdt 3.0의 핵심은 Countdown Timer이다패킷을 보내고 일정 시간(Timeout) 동안 대답이 없으면 잃어버린 것으로 간주하고 다시 보냅니다.
1단계: 0번 패킷 전송 (Wait for call 0 from above)
- (1) 이벤트: rdt_send(data) (데이터가 내려옴)
- (2) 액션 1: sndpkt = make_pkt(0, data, checksum) (0번 패킷 생성)
- (3) 액션 2: udt_send(sndpkt) (패킷 전송)
- (4) 액션 3: start_timer (유실을 확인하기 위해 타이머 시작)
2단계: 0번 ACK 확인 대기 (Wait for ACK 0)
이 상태에서는 '유실' 상황을 처리하는 액션이 추가됩니다.
- 상황 A: 잘못된 응답이 온 경우 (무시)
- (5) 이벤트: rdt_rcv(rcvpkt) && (corrupt(rcvpkt) || isACK(rcvpkt, 1)) (내용이 깨졌거나 1번 ACK가 온 경우)
- (6) 액션: $\Lambda$ (아무것도 하지 않고 계속 기다림)
- 상황 B: 기다려도 응답이 없는 경우 (타임아웃)
- (7) 이벤트: timeout (합리적인 시간만큼 기다렸으나 대답이 없음)
- (8) 액션 1: udt_send(sndpkt) (패킷을 다시 전송)
- (9) 액션 2: start_timer (타이머 다시 시작)
- 상황 C: 정확한 응답이 온 경우 (성공)
- (10) 이벤트: rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt, 0) (멀쩡한 0번 ACK 도착)
- (11) 액션: stop_timer (무사히 받았으니 타이머 정지)
- 결과: 1번 패킷 전송 단계로 이동
3단계: 1번 패킷 전송 (Wait for call 1 from above)
- (12) 이벤트: rdt_send(data)
- (13) 액션: 패킷 생성 → 전송 → start_timer
4단계: 1번 ACK 확인 대기 (Wait for ACK 1)
- 상황 A (잘못된 응답): 깨졌거나 0번 ACK가 오면 무시($\Lambda$)
- 상황 B (타임아웃): 대답이 없으면 패킷 재전송 후 타이머 다시 시작
- 상황 C (정상 수신): 멀쩡한 1번 ACK가 오면 stop_timer 후 다시 0번 대기 상태로 복귀
|
수신측
수신측이 **0번 패킷을 기다리는 상태(Wait for 0 from below)**를 기준으로 설명한다 * 수신측은 rdt 2.2와 같은 메커니즘이다
1단계: 패킷 수신 및 상태 확인 (Wait for 0 from below)
수신자는 송신자로부터 패킷이 오기를 기다린다
- 상황 A: 패킷이 깨졌거나 1번 패킷(이전 패킷)이 온 경우 (실패)
- (1) 이벤트: rdt_rcv(rcvpkt) && (corrupt(rcvpkt) || has_seq1(rcvpkt))
- 패킷이 오는 도중 망가졌거나(corrupt), 내가 기다리는 0번이 아니라 이미 받았던 1번 패킷이 다시 온 상황이다
- (2) 액션: udt_send(sndpkt)
- 새로운 ACK를 만들지 않고, **가장 최근에 성공했던 1번 패킷에 대한 ACK(ACK 1)**를 다시 보낸다
- 결과: 0번을 계속 기다려야 하므로 자기 자신의 상태로 돌아온다
- 상황 B: 0번 패킷이 제대로 온 경우 (성공)
- (3) 이벤트: rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq0(rcvpkt)
- 패킷이 깨지지 않았고(notcorrupt), 기다리던 0번 패킷이 정확히 도착함
- (4) 액션 1: extract(rcvpkt, data)
- (5) 액션 2: deliver_data(data)
- (6) 액션 3: sndpkt = make_pkt(ACK0, chksum)
- "0번을 잘 받았다"는 의미로 ACK 0 패킷을 새로 만듦
- (7) 액션 4: udt_send(sndpkt)
결과: 0번 처리가 끝났으므로 다음 상태(1번 패킷을 기다리는 상태)로 넘어감
2단계: 1번 패킷 기다리기 (Wait for 1 from below)
0번 패킷 처리를 무사히 마치고, 이제 1번 패킷이 오기를 기다리는 상태
- 상황 A: 패킷이 깨졌거나 0번 패킷(이전 패킷)이 온 경우 (실패)
- (8) 이벤트: rdt_rcv(rcvpkt) && (corrupt(rcvpkt) || has_seq0(rcvpkt))
- 내용: 패킷이 훼손되었거나, 이미 처리한 0번 패킷이 다시 온 상황
- (9) 액션: udt_send(sndpkt) (가장 최근에 성공했던 ACK 0를 다시 보냄)
- 결과: 1번을 계속 기다려야 하므로 자기 자신의 상태로 돌아옴
- 상황 B: 1번 패킷이 제대로 온 경우 (성공)
- (10) 이벤트: rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq1(rcvpkt)
- 내용: 기다리던 1번 패킷이 깨지지 않고 정확히 도착함
- (11) 액션: 데이터 추출 → 앱으로 전달 → ACK 1 패킷 생성 → 송신자에게 전송
- 결과: 1번 처리가 끝났으므로 다시 처음 상태(0번 패킷 대기)로 돌아감
|