어플리케이션 계층 2

윤상준·2022년 4월 3일
0

네트워크

목록 보기
4/19
post-thumbnail
post-custom-banner

Reliable Data Transfer (RDT)

전송 계층의 대표적인 프로토콜 중 하나인 TCP는 신뢰성이 높다. 신뢰성이 높다는 말은 주고받는 데이터의 유실이 발생하지 않는다는 것을 의미한다.

그림에서 왼쪽의 통신은 신뢰성이 보장되지만, 그 하위계층에서 이루어지는 오른쪽의 통신은 신뢰성이 보장되지 않는다.

이처럼 전송 계층 밑의 계층에서 라우터를 통해 이루어지는 통신은 신뢰적이지 않다. 비신뢰적인 통신에서는 패킷 에러와 패킷 유실이 발생할 수 있다.

  • 패킷 에러 : 패킷에 문제가 생겨서 내용이 변경될 수 있다.
  • 패킷 유실 : 패킷이 전송되는 도중에 유실되어 사라질 수 있다.

패킷 에러와 유실만 잘 처리해주면 신뢰성있는 전송이 가능하며, 전송 계층에서 메세지 에러와 유실을 체크해줘야 한다.

RDT Protocol

전송 계층에서 신뢰성있는 통신이 이루어지도록 하기 위한 프로토콜을 RDT 프로토콜이라고 한다.

RDT 1.0 (완벽하게 신뢰적인 채널에서의 데이터 전송)

RDT 1.0은 통신 채널은 완벽하게 신뢰적이며 신뢰성 있는 데이터 전송이 보장된다는 것을 가정한다.

따라서 전송자는 데이터의 전송만 하면 되고 수신자는 데이터의 수신만 하면 된다. 또한 완벽하게 신뢰적이므로 패킷 에러와 패킷 유실은 발생하지 않는다.

하지만 RDT 1.0에서 가정하는 완벽하게 신뢰적인 상황은 비현실적이다.

RDT 2.0 (패킷 에러가 발생할 수 있는 채널에서의 데이터 전송)

RDT 2.0은 통신 과정에서 패킷 에러가 발생할 수 있는 상황을 가정한다. (패킷 유실은 고려하지 않는다.)

큰 맥락에서 RDT 2.0의 동작 방식은 다음과 같다.

  1. 전송자가 패킷을 보낸다.
  2. 수신자는 패킷을 받고 그에 대한 피드백을 보낸다. (ACK / NAK)
  3. 만약 NAK 즉, 패킷이 제대로 오지 않았다는 피드백을 받으면 전송자는 패킷을 재전송한다.

RDT 2.0에서는 다음과 같은 매커니즘이 필요하다.

에러 감지 (Error Detection)

패킷의 헤더에 에러 여부를 판단하는 CheckSum 비트를 추가하여 에러 여부를 판단한다.

피드백 (Feedback)

수신자는 데이터를 받을 때, 데이터를 오류 없이 잘 받았는지를 전송자에게 알려주기 위해 ACK, NAK 피드백을 전송한다.

  • ACK (Acknowledgement) : 패킷이 정상적으로 잘 도착했다을 때 보낸다.
  • NAK (Negative Acknowledgement) : 수신한 패킷에 에러가 있을 때 보낸다.

재전송 (Retransmission)

전송자는 NAK 피드백을 받았다면 이전에 보낸 패킷을 재전송한다.

이처럼 RDT 2.0에서는 수신한 데이터에 대해 피드백을 보내면서 데이터의 신뢰성을 보장한다.

이처럼 재전송을 기반으로 한 신뢰성있는 데이터 전송 프로토콜을 자동재전송요구(Automatic Repeat reQuest, ARQ protocol) 프로토콜이라고 한다.

유의할 점은 이때 전송자가 ACK 또는 NAK를 기다리는 수신 대기상태에서는 상위 계층으로 부터 더 이상 데이터를 전달 받을 수 없다는 점이다. 따라서 rdt2.0 프로토콜은 전송 후 대기(Stop-and-Wait)프로토콜 이라고도 한다.

RDT 2.1

하지만 RDT 2.0의 방식으로는 신뢰성을 100% 보장하지 못한다.
피드백이 손상된다면?

만약에 수신자는 패킷을 잘 받아서 ACK 피드백을 보냈는데 이 ACK 피드백이 손상된 채 전송되어서, 전송자 입장에서 이 패킷이 제대로 전송되었는지 아닌지 알 수 없는 경우가 생길 수 있다.

이 경우 전송자는 해당 패킷을 무조건 다시 보낸다.

그러면 수신자 입장에서는 새로 받은 패킷이 기존에 ACK 처리한 패킷과 동일한 중복 패킷인지 아니면 완전 새로운 패킷인지 알 길이 없다. 따라서 이를 식별하기 위한 추가적인 방법이 필요하다.

Sequence Number (시퀀스 넘버)

이를 해결하기 위해 나온 방법은 패킷에 번호를 붙이는 방법이다. 이때 붙이는 번호를 시퀀스 넘버라고 한다.

전송자는 패킷의 헤더에 0번, 1번 ... 으로 번호를 붙여 보낸다. 수신자는 이 시퀀스 넘버를 토대로 이 패킷이 중복 패킷인지 완전 새로운 패킷인지를 구별할 수 있다. (0번 패킷 이후 0번 패킷이 또 들어왔다면 중복된 패킷이라고 판단)

수신자는 중복된 패킷이 들어왔다면 이를 폐기한다.

이때 각 패킷의 헤더 크기는 한정되어있으므로 시퀀스 넘버 전용 필드를 최소화 할 필요가 있다. 그렇다면 시퀀스 넘버는 몇 개 정도가 필요할까? 2개면 충분하다.

0번과 1번만을 사용한다고 해보자.

전송자가 0번 패킷을 보내고 수신자가 정상적으로 받았다면, 전송자는 다음으로 1번을 보낸다. 수신자가 1번 역시 정상적으로 받았다면, 전송자는 다시 패킷에 0번을 적어 보낸다.

이처럼 적은 수의 시퀀스 넘버를 재사용하여 필드 크기를 최소화 할 수 있다.

RDT 2.2 : a NAK-free Protocol

이름에서 알 수 있듯이 NAK 없이 ACK만 사용하는 프로토콜이다.

수신자는 패킷을 받으면 무조건 ACK만 보낸다.
다만 이 ACK 안에 가장 최근에 정상적으로 받은 시퀀스 넘버를 포함해서 보낸다.

만약 NAK을 보내야 할 상황이라면 수신자는 그 전에 가장 마지막으로 받은 정상 패킷의 시퀀스 넘버를 보내므로, 전송자 입장에서는 중복된 ACK을 받게 된다. 따라서 전송자는 그 다음 패킷을 재전송한다.

RDT 3.0 : Channel with loss & packet errors

RDT 3.0은 패킷 에러와 유실 전부를 처리하는 프로토콜이다.

이를 위해 사용하는 방법은 타이머이다.

RDT 3.0에서는 전송자가 보냈던 패킷이 유실되어버리면 수신자는 아무것도 받지 못하므로, 아무런 피드백을 주지 않는다.

전송자는 패킷을 보내고 일정 시간이 지났는데도 아무런 응답이 오지 않는다면 문제가 생겼다고 판단하고 패킷을 재전송한다.

이때 일정 시간을 기다렸는데도 아무런 응답이 오지 않는 상황을 Time-Out이라고 한다.

타이머의 시간을 어느정도로 맞춰야 할 지는 정답이 없다. 다만 타이머가 너무 짧으면 그만큼 통신 속도는 빨라지지만 네트워크 오버헤드가 커지고, 너무 길면 네트워크 오버헤드는 작지만 실제 에러가 발생했을 때 대응이 느려지게 된다. 따라서 설계자가 합리적인 수준의 타이머를 설정해야한다.

만약 전송자가 보낸 패킷이 유실된 것이 아니라 단순히 느리게 전송되고 있는 상황이라면, 어쨋든 전송자 입장에서는 Time-Out이 발생해서 해당 패킷을 재전송할 것이다. 결과적으로 중복된 패킷이 전송될텐데 수신자는 시퀀스 넘버를 통해 이에 대응할 수 있다.

Recap : Principles of Reliable Data Transfer

  • 비신뢰적인 채널에서는 패킷 에러패킷 유실이 발생할 수 있다.
  • 패킷 에러에 대응하기 위해서는 에러 감지, 피드백, 재전송, 시퀀스 넘버 매커니즘을 사용한다.
  • 패킷 유실에 대응하기 위해서는 타임 아웃 매커니즘을 사용한다.
  • 실제 세상에서 사용하는 프로토콜 (ex. TCP)은 훨씬 더 복잡한 방식을 사용하지만 기본 원칙은 위와 같다.

Pipelined Protocols

실제 세상에서는 보내야할 패킷은 많은데 RDT 3.0 방식을 통해 패킷을 하나씩 전송하면 많은 패킷 낭비가 발생한다.

왜냐하면 패킷 하나를 전송하고나서 ACK이 올 때까지 그 소켓은 다른 어떤 통신도 할 수 없기 때문이다.

이에 대응하기 위해서 실제로는 파이프라인 프로토콜을 사용한다.

파이프라인 프로토콜이란 패킷을 한번에 대량으로 보내고, 그에 대한 피드백 역시 대량으로 받는 방식이다. 이를 통해 많은 양의 패킷을 주고 받을 수 있고 패킷 낭비를 줄일 수 있다.

하지만 수신자 입장에서는 어떤 패킷을 먼저 처리하고 피드백을 줘야할지 혼란스러울 수 있다. 이를 위해 go-Back-N, Selective Repeat 프로토콜을 추가로 사용할 수 있다.

profile
하고싶은건 많은데 시간이 없다!
post-custom-banner

0개의 댓글