본문 바로가기
Infra & Security Eng/Network & Security

[네트워크] TCP 신뢰적 데이터 전송 원리: RDT 1.0부터 2.0까지 완벽 정리

by 엔지니어 E 2026. 2. 10.
반응형

신뢰적 Data transfer (TCP)

송신측 (Sender Side): 데이터를 보내는 과정

애플리케이션이 데이터를 아래로 내려보내는 '이벤트'에서 시작
  1. rdt_send() (호출)
    • 누가? 상위 애플리케이션이 TCP에게
    • 내용: "이 데이터 좀 전달해 줘!" 하고 데이터를 내려보내는 단계
  2. udt_send() (전송)
    • 누가? TCP가 하위 계층(IP)에게
    • 내용: 받은 데이터를 '패킷'이라는 단위로 포장해서, 비신뢰적인 하위 채널(Unreliable channel)로 실제로 쏘는 단계여기서 udt는 Unreliable Data Transfer의 약자

수신측 (Receive Side): 데이터를 받는 과정

불안정한 채널을 뚫고 올라온 패킷을 다시 애플리케이션에 전달하는 과정
  1. rdt_rcv() (수신)
    • 누가? 하위 채널로부터 TCP가
    • 내용: 패킷이 도착하면 호출됩니다. 이 패킷 안에 오류가 없는지, 순서는 맞는지 체크하며 위로 올릴 준비
  2. deliver_data() (배달)
    • 누가? TCP가 상위 애플리케이션에게
    • 내용: 패킷에서 순수한 '데이터'만 쏙 뽑아내서, 기다리고 있는 애플리케이션에게 최종적으로 전달

 

신뢰적 데이터 전송: RDT 1.0 (가장 이상적인 상태)

이 모델은 하위 채널이 완전히 신뢰적이라고 가정한다. 즉, 전송 중에 비트 오류(Bit error)가 발생하지 않고, 패킷이 유실(Loss)될 걱정도 전혀 없는 '무결점' 상태를 말한다
1. 송신측(Sender): 데이터를 보내는 과정
송신측은 항상 상위 레이어(애플리케이션)로부터 데이터가 내려오길 기다리는 상태에 있다

이벤트 발생: 애플리케이션으로부터 데이터가 내려온다 (rdt_send(data))
패킷 생성: 전달받은 데이터를 전송용 패킷으로 만든다 (make_pkt(data))
데이터 전송: udt_send(packet)을 통해 하위 레이어(네트워크)로 패킷을 보낸다 
상태 복귀: 전송 후 다시 상위 레이어로부터 다음 데이터가 오기를 기다리는 상태로 돌아간다


2. 수신측(Receiver): 데이터를 받는 과정 
수신측은 반대로 하위 레이어(IP)로부터 패킷이 올라오기를 기다리는 상태에 있다

1. 이벤트 발생: 하위 레이어에서 패킷이 도착한다(rdt_rct(packet))
2. 데이터 추출: 도착한 패킷으로부터 순수한 데이터를 뽑아낸다(extract(packet,data))
3. 최종 전달: 추출한 데이터를 상위 애플리케이션으로 전달한다(deliver_data(data))
4. 상태 복귀: 전달을 마친 후 다시 다음 패킷이 오기를 기다리는 상태로 돌아간다

 

RDT 2.0: 패킷이 깨질 수 있는 채널 (Bit Error)

RDT 1.0과 달리 데이터가 가다가 비트(BIT)가 뒤바뀌어 패킷이 깨질 수 있는 상황을 가정 한다. 패킷이 사라지지는 않지만, 내용이 변질 될 수 있기 때문에 이글 해결하기 위한 장치가 추가 된다
1. [송신측] 데이터 포장 및 에러 검출 준비 
동작: 상위 애플리케이션에서 받은 데이터 에 "Checksum(체크섬)"을 붙여서 패킷을 만든다 
이유: 패킷이 가다가 깨졌을 확률이 있으므로 수신측이 이를 감지할 수 있는 눈을 달아주는 과정
-> 이는 수신측이 패킷의 무결성을 검증할 수 있도록 하기 위함

2. [송신측] 전송 및 대기(Stop-and-Wait)
동작: udt_send로  패킷을 보낸 후, 곧바로 다음 데이터를 보내지 않고, 수신측의 대답(ACK/NAK)이 올 때까지 기다린다
핵심: 이를 Stop-and-Wait 방식이라고 하며, 상대방의 상태를 확인하며 전송하는 신뢰성 있는 방식의 시작이다 

3. [수신측] 패킷 검사(Checksum 계산)
동작: 패킷을 받은 수신측은 동봉된 Checksum을 계산해서 패킷이 정상인지, 아니면 전송 중에 깨졌는지 확인한다 

4. [수신측] 피드백 발송(ACK/NAK)
정상 수신 시: 데이터가 깨지지 않았다면 ACK(Positive Acknowledgement) 메시지를 송신측에 보낸다
오류 감지 시: 패킷이 깨졌다면 NAK(Negative Acknowledgement) 메시지를 보내 재전송을 요청 한다

5.[송신측] 피드백 분석 및 후속 조치
ACK 수신 시: 전송 성공으로 판단하고 대기 상태를 종료하며, 다음 데이터 전송을 준비 한다 
NAK 수신 시: 전송 실패로 판단하여 해당 패킷을 다시 하위 채널로 재선송 한다 

 

rdt 2.0: FSM

FSM (Finite State Machine) 개념
FSM은 시스템의 동작을 **'상태'**와 **'이벤트'**를 중심으로 설계한 논리적 설계도

정의: 시스템이 가질 수 있는 유한한 수의 **상태(State)**를 정의하고, 외부의 **이벤트(Event)**에 따라 한 상태에서 다른 상태로 어떻게 변화(Transition)하는지 나타낸 모델

표기법
동그라미: 현재 시스템이 처한 특정 상태
화살표: 이벤트 발생 시 상태가 이동하는 경로
가로선 위 (Condition): 이 동작이 일어나기 위한 **전제 조건(이벤트)**
가로선 아래 (Action): 조건이 만족되었을 때 시스템이 수행하는 실제 동작

 

RDT 2.0: 주체별 이벤트 & 액션 상세 분석

데이터 패킷을 보내는 주체: Sender
제어 패킷(ACK/NAK)을 보내는 주체: Receiver

[송신측: Sender Side]
애플리케이션 계층 (Upper Layer): 데이터를 생성하는 주체. rdt_send(data)를 호출하여 전송을 요청
트랜스포트 계층 (RDT Sender): 데이터에 Checksum을 붙여 패킷(Packet)을 생성
네트워크 계층 (Lower Layer / UDT): udt_send(packet)를 호출하여 물리적인 전송을 위임 (여기서 UDT는 Unreliable Data Transfer, 즉 비신뢰적 채널인 IP 계층 등을 의미)

[수신측: Receiver Side]
네트워크 계층 (Lower Layer): 하드웨어로부터 들어온 신호를 패킷화하여 위로 올린다 rdt_rcv(packet) 이벤트가 발생.
트랜스포트 계층 (RDT Receiver): 패킷의 Checksum을 확인하여 **에러 검출(Error Detection)**을 수행
애플리케이션 계층 (Upper Layer): 데이터가 멀쩡하다면 deliver_data(data)를 통해 최종 수신 프로세스에게 데이터를 전달
송신측(Sender) 프로세스
1단계: 데이터 전송 대기(Wait for call from above)
이벤트(rdt_send): rdt_send(data) * 주체: 상위 어플리케이션이 RDT를 호출함
액션(make_pkt, udt_send): RDT가 스스로를 패킷화(make_pkt) 하고, 하위 네트워크(UDT)를 향해 전송(udt_send) 함 

2단계: 확인 응답 대기(wait for ACK of NAK)
이벤트(rdt_rcv): 하위 네트워크(UDT)를 통해 수신측의 응답이 도착함
액션(isNAK, isACK)
경로 A(isNAK): RDT가 하위 네트워크(UDT)를 향해 기존 패킷을 다시 전송함
경로 B(isACK): RDT가 아무 동작도 하지 않고 (Λ) , 상태만 전이함(다음 단계로 넘어감)

수신측(Receiver) 프로세스
단일단계: 패킷 수신 대기(Wait for call from below) 
이벤트: rdt_rcv(rcvpkt)
주체: 하위 네트워크(udt)를 통해 송신측의 패킷이 나에게 도착함
액션(corrupt, notcorrupt)
경로 A(깨졌을 때 - corupt): RDT가 하위 네트워크(UDT)를 향해 NAK 신호를 전송함
경로 B(멀쩡할 때 - notcorrupt):
1. RDT가 데이터를 추출하여 상위 애플리케이션에게 전달(deliver_data)함
2. RDT가 하위 네트워크(UDT)를 향해 ACK 신호를 전송함

 

rdt 2.0: 치명적인 결함

 ACK/NAK가 훼손 되는 경우 
수신자가 "잘 받았어(ACK)" 혹은 "깨졌어"(NAK)"라고 대답을 보냈는데, 이 응답 자체가 전송 중에 훼손 되는 경우

송신자는 수신자에게 어떤 일이 벌어졌는지(정상 수신인지 오류인지) 알 수 없다. 송신자는 대답을 못 알아들으면 안전을 위해 데이터를 재전송하게 되는데 이때 수신자는 이미 받은 데이터를 또 받게 되는 중복 상태에 빠지게 된다 (재전송으로 인한 packet 중복)

packet 중복 제어 방법 
1. Secuence Number 추가 
- 송신자는 패킷에 0번, 1번 번호를 붙여 보낸다 
- 이를 통해 수신자는 방금 온 패킷이 새로운 것인지 다시 보낸 중복된 것인지 알 수 있다

2. 중복 제어
수신자는 이미 받은 번호의 패킷이 다시 오면 저장하지 않고 버린다 

3. Stop-and-wait(멈추고 기다리기)
- 송신자는 패킷 하나를 전송한 후, 수신자로부터 제대로 된 응답(Response)이 올 때까지 기다린다 
- 만약 응답이 깨져서 오면 송신자는 패킷을 재전송하고, 다시 응답을 기다린다