신뢰적인 데이터 전송
- 신뢰적인 데이터 전송 문제는 트랜스포트 계층뿐만 아니라 링크 계층과 애플리케이션 계층에서도 발생할 수 있는 문제이므로 이 절에서는 일반적인 상황을 다룬다.
- 신뢰적인 데이터 전송 프로토콜의 의무는 신뢰적인 채널의 서비스 추상화를 구현하는 것이다.
- 신뢰적인 채널에서는 전송된 데이터가 손상되거나 손실되지 않으며, 모든 데이터는 전송된 순서 그대로 전달된다. (TCP가 인터넷 애플리케이션에게 제공하는 서비스 모델)
- 이 작업은 신뢰적인 전송 프로토콜 '아래에 있는 계층'이 비신뢰적일 수 있어서 어려워진다. 그 예로 TCP는 비신뢰적인 종단간의 네트워크 계층(IP)의 바로 상위에 구현된 신뢰적인 데이터 전송 프로토콜이다.
이 절에서는 하위 채널 모델을 고려하여 신뢰적인 데이터 전송 프로토콜의 송신자와 수신자 측면을 점진적으로 개발해나간다. 예를 들어 하위 채널에서 비트가 손상되거나, 전체 패킷을 손실하는 경우 어떤 프로토콜 매커니즘이 필요한지를 고려할 것이다.
채택할 한 가지 가정은 보내진 패킷은 일부 손실될 수는 있겠지만 보내진 순서대로 전달된다.
- 이 그림은 데이터 전송 프로토콜의 인터페이스를 나타낸다.
- 데이터 전송 프로토콜의 송신측은 rdt_send()로 위쪽으로부터 호출될 것이며, 수신측은 상위 계층으로 전달될 데이터를 넘길 것이다.
- rdt 프로토콜: reliable data transfer / _send(): rdt의 송신측이 호출되고 있음
- 수신측에서 rdt_rcv()는 패킷이 채널의 수신측으로부터 도착했을 때 호출된다.
- rdt 프로토콜이 상위 계층에 데이터를 전달하려고 할 때 deliver_data()를 호출한다.
이제부터 프로토콜 데이터 단위에 대해 '세그먼트' 대신 '패킷'이라는 용어를 사용한다. 여기서 전개되는 이론은 컴퓨터 네트워크 전반적으로 적용되는 것이고 단지 인터넷 트랜스포트 계층에만 적용하는 것이 아니기 때문이다.
이 절에서는 단방향 데이터 전송인 송신측으로부터 수신측까지의 데이터 전송만을 고려한다.
- 단방향 데이터 전송만해도 프로토콜의 송신측과 수신측이 양방향으로 패킷을 전달해야 하므로, 전송 데이터를 포함하는 패킷을 교환하는 것 외에 제어 패킷을 양쪽으로 전송해야 한다.
- rdt의 송신측과 수신측 모두 udt_send()를 호출함으로써 다른 쪽에 패킷을 전송한다.
신뢰적인 데이터 전송 프로토콜의 구축
유한상태 머신(FSM)
- FSM의 초기 상태는 점선 화살표로 표시된다.
- 화살표는 한 상태로부터 다른 상태로의 전이를 나타낸다.
- 전이를 일으키는 이벤트(event)는 변화를 표기하는 가로선 위에 나타낸다.
- 이벤트가 발생했을 때 취해지는 행동, 액션(action)은 가로선 아래에 나타낸다.
rdt 1.0: 완벽하게 신뢰적인 채널상에서의 신뢰적인 데이터 전송
하위 채널이 완전히 신뢰적인 가장 간단한 경우를 고려해보자.
송신자, 수신자 각각에 대해 분리된 FSM이 있다.
a: 송신자의 동작에 대한 정의
b: 수신자의 동작에 대한 정의
- rdt 1.0에서 송신자와 수신자 FSM은 각각 하나의 상태만을 가지므로, 전이는 필연적으로 그 상태로부터 자신으로 되돌아온다.
- 송신자의 동작
- rdt_send(data)에 의해 상위 계층으로부터 data를 받아들인다.
- make_pkt(data)로 data를 포함한 패킷을 생성한다.
- 그 후 패킷을 채널로 송신한다.
- 수신자의 동작
- rdt_rcv(packet)에 의해 하위 채널로부터 패킷을 수신한다.
- extract(packet, data)로 패킷으로부터 data를 추출한다.
- deliever_data(data)로 data를 상위 계층으로 전달한다.
- 여기서는 데이터 단위와 패킷이 차이가 없으며, 모든 패킷 흐름은 송신자 → 수신자까지다.
- 완전히 신뢰적인 채널에서는 오류가 생길 수 없으므로 수신측이 송신측에게 어떤 피드백도 제공할 필요가 없다.
- 또한, 수신자는 송신자가 데이터를 송신하자마자 데이터를 수신할 수 있으므로, 수신자가 송신자에게 천천히 보내라는 것을 요청할 필요가 없다.
rdt 2.0: 비트 오류가 있는 채널상에서의 신뢰적인 데이터 전송
- 패킷 안의 비트들이 하위 채널에서 손상되는 모델이다.
- 이러한 비트 오류는 패킷이 전송/전파/버퍼링 될 때 네트워크의 물리적인 구성요소에서 일반적으로 발생한다.
- 전송된 모든 패킷이 송신된 순서대로(비록 패킷의 비트가 손상되더라도) 수신된다고 계속 가정한다.
자동 재전송 요구(ARQ) 프로토콜
- 마치 전화통화에서 긴 메시지를 보냈을 때 수신자가 이해하고 기록한 후에 "OK"를 말하거나, 제대로 듣지 못했다면 "반복하라"고 요청하는 것과 비슷하다.
- 긍정 확인 응답(ACK)과 부정 확인 응답(NAK)을 둘다 사용하여 수신자가 송신자에게 메시지가 정확히 수신되었는지 아닌지를 알려줄 수 있게 한다.
ARQ 프로토콜에는 다음 3가지 부가 프로토콜 기능이 비트 오류를 처리하기 위해 필요하다.
- 오류 검출
- 비트 오류가 발생했을 때 수신자가 검출할 수 있는 기능이 필요하다.
- 앞 절에서의 UDP는 이러한 목적을 위해 체크섬 필드를 사용한다.
- 이러한 기술이 송신자로부터 수신자에게 전송되는 추가적인 비트들을 요구한다. → rdt 2.0 데이터 패킷의 패킷 체크섬 필드로 모아질 것이다.
- 수신자 피드백
- 송신자와 수신자는 일반적으로 수천 킬로미터 떨어진 각기 다른 종단 시스템에서 동작하므로, 송신자가 수신자의 상태(패킷 수신 여부 등)를 알기 위한 유일한 방법은 수신자가 송신자에게 피드백을 제공하는 것이다.
- rdt 2.0에서는 수신자로부터 송신자 쪽으로 ACK와 NAK 패킷을 전송할 것이다. (이 패킷은 단지 한비트 길이면 된다.)
- 재전송
- 수신자에서 오류를 가지고 수신된 패킷은 송신자에 의해 재전송된다.
다음은 오류 검출, 긍정 확인응답과 부정 확인응답을 채택하는 rdt 2.0의 FSM을 보여준다.
- 송신자: 2개의 상태를 갖는다.
- 가장 왼쪽 상태에서 송신자 프로토콜은 상위 계층으로부터 데이터가 전달되기를 기다린다.
- 가장 오른쪽 상태에서 송신자 프로토콜은 수신자로부터의 ACK 또는 NAK 패킷을 기다린다.
- 송신자가 ACK 또는 NAK를 기다리는 상태에 있을 때, 상위 계층으로부터 더이상의 데이터를 받을 수 없다. (rdt_send X)
- rdt 2.0과 같은 프로토콜은 전송 후 대기 프로토콜이다.
- 수신자: 아직 단일 상태를 갖는다.
- 패킷이 도착했을 때, 수신자는 수신된 패킷이 손상되었는지 아닌지에 따라 ACK 또는 NAK로 응답한다.
rdt 2.0의 결함
- 여기서는 ACK 또는 NAK 패킷이 손상될 수 있다는 가능성은 고려하지 않았다.
- 만약 ACK 또는 NAK가 손상되었다면, 송신자는 수신자가 전송된 데이터의 마지막 부분을 올바르게 수신했는지를 알 방법이 없다.
- 대안 1) 송신자가 검출뿐만 아니라 비트 오류로부터 회복할 수 있도록 충분한 체크섬 비트들을 추가한다.
- 이 방식은 패킷이 손상될 수는 있으나 손실되진 않은 채널의 경우 즉각적으로 문제가 해결된다.
- 대안 2) 송신자가 왜곡된 ACK/NAK 패킷을 수신할 때 현재 데이터 패킷을 단순히 다시 송신한다.
- 그러나 이 방식은 송신자에서 수신자 간의 채널로 중복 패킷을 전송한다.
- 중복 패킷의 가장 근본적으로 어려운 점은 마지막으로 전송된 ACK 또는 NAK가 송신자에게 정확하게 수신됐는지를 알 수 없다는 것이다. 그러므로 도착하는 패킷이 새로운 데이터를 포함하는 것인지 재전송인지를 알 수 없다.
해결책
- 데이터 패킷에 새로운 필드를 추가하고, 이 필드 안에 순서번호를 삽입하는 방식으로, 데이터 패킷에 송신자가 번호를 붙인다. (TCP를 포함한 모든 현존하는 데이터 전송 프로토콜에 채택된 방법)
- 수신자는 수신된 패킷이 재전송인지를 결정할 때 이 순서번호만 확인하면 된다.
- 재전송된 패킷: 가장 최근에 수신된 패킷과 같은 순서번호를 가짐
- 새로운 패킷: 순서번호가 변하면, %2 연산을 수행함
rdt 2.1: rdt 2.0의 수정 버전
- rdt 2.1의 송신자와 수신자 FSM은 2.0보다 두 배 많은 상태를 가지고 있다.
- 다음 2가지를 반영하기 때문이다.
- 프로토콜 상태가 현재 (송신자에 의해) 전송되고 있는지에 대한 반영
- (수신자가) 기다리고 있는 패킷이 순서번호 0 또는 1을 가져야 하는지에 대한 반영
- rdt 2.1은 수신자로부터 송신자까지의 긍정 확인응답과 부정 확인응답을 모두 포함한다.
- 순서가 바뀐 패킷이 수신되면, 수신자는 이미 전에 수신한 패킷에 대한 긍정 확인응답을 전송한다. → NAK를 송신하는 대신에 가장 최근에 정확하게 수신된 패킷에 대해 ACK를 송신함으로써 같은 효과를 얻을 수 있다.
- 손상된 패킷이 수신되면, 수신자는 부정 확인응답을 전송한다.
- 즉, 같은 패킷에 대해 2개의 ACK를 수신한 송신자는 수신자가 2번 ACK한 패킷의 다음 패킷을 정확하게 수신하지 못했다는 것을 알게 된다.
rdt 2.2: 비트 오류를 갖는 채널을 위한 NAK 없는 신뢰적인 데이터 전송
- rdt 2.1과 미묘한 차이는 수신자가 반드시 ACK 메시지에 의해 확인응답되는 패킷의 순서번호를 포함해야 한다는 점이다. → 이는 수신자 FSM의 make_pkt()에 ACK,0 또는 ACK,1 인 인수를 넣어서 수행한다.
- 그리고 송신자는 수신된 ACK 메시지에 의해 확인응답된 패킷의 순서번호를 반드시 검사해야만 한다. → 이는 송신자 FSM의 isACK()에 0 또는 1 인 인수를 넣어서 수행한다.
rdt 3.0: 비트 오류와 손실이 있는 채널에서의 신뢰적인 데이터 전송
- 하위 채널이 패킷을 손실하는 경우도 생각해보자. 다음의 2가지 부가 내용을 프로토콜이 다뤄야 한다.
- 어떻게 패킷 손실을 검출할 것인가?
- 패킷 손실이 발생했을 때 어떤 행동을 할 것인가?
- 여기서는 송신자에게 손실된 패킷의 검출과 회복의 책임을 부여한다.
- 만약 송신자가 패킷을 잃어버렸다고 확신할 정도로 충분한 시간을 기다릴 수만 있으면, 데이터 패킷은 간단하게 재전송될 수 있다.
- 송신자가 어떤 패킷을 손실했다는 것을 확신하기 위해 기다려야 하는 최소한의 시간은 다음과 같다.
→ 송신자와 수신자 사이의 왕복 시간 지연(중간 라우터에서의 버퍼링을 포함) + 수신측에서 패킷을 처리하는데 필요한 시간 - 실제 상황에서 채택한 접근 방식은 손실이 일어났을 만한 시간을 현명하게 선택하여, 만일 ACK가 이 시간안에 수신되지 않으면 패킷은 재전송된다.
- 이건 송신자 대 수신자 채널에서 중복 데이터 패킷의 가능성을 포함하나, rdt 2.2처럼 패킷의 순서번호를 통해 처리가 가능하다.
- 시간 기반의 재전송 메커니즘을 구현하기 위해, 주어진 시간이 지난 후에 송신자를 인터럽트(중단)할 수 있는 카운트다운 타이머가 필요하다. 그러므로 송신자는 다음처럼 동작해야 한다.
- 매 패킷(1번째 또는 재전송)이 송신된 시간에 타이머를 시작한다.
- 타이머 인터럽트에 적당한 반응을 취한다.
- 타이머를 멈춘다.
- 패킷의 순서번호가 0과 1이 번갈아 일어나므로 rdt 3.0은 때때로 얼터네이팅 비트 프로토콜이라고 부른다.
'CS > 네트워크' 카테고리의 다른 글
TCP (1) | 2023.11.28 |
---|---|
파이프라이닝된 신뢰적인 데이터 전송 프로토콜 (0) | 2023.11.16 |
비연결형 트랜스포트: UDP (0) | 2023.11.11 |
다중화와 역다중화 (0) | 2023.11.11 |
트랜스포트 계층 (0) | 2023.11.08 |