wanna be dev 🧑‍💻

Cool 하고 Sick한 개발자가 되고 싶은 uzun입니다

A.K.A. Kick-snare, hyjhyj0901, h_uz99 solvedac-logo

Computer Science/Computer Network

📡 [Network] 전송층에서 신뢰성있는 데이터의 전송 (가상의 프로토콜 구축해보기)

Kick_snare 2022. 10. 11. 20:15
728x90

본 포스팅은 < 컴퓨터 네트워킹 하향식 접근[8판] James F. Kurose, Keith W. Ross 저/최종원, 강현국, 김기태 > 을 참고하여 작성되었습니다.

Ch03 Transport Layer

4. Principles of reliable data transfer

: 신뢰성있는 데이터 전송

신뢰성 있는 데이터의 전송을 구현하는 문제는 전송층 뿐만 아니라 링크 계층에서도 발생할 수 있는 문제이다. 이는 네트워킹에서 매우 중요하다.

상위 계층 객체에게 데이터에게 제공되는 서비스의 추상화는 데이터가 전송될 수 있는 신뢰적인 채널의 서비스 추상화이다. 신뢰적인 채널에서는 데이터가 손상되거나 손실되지 않는다.

신뢰적인 데이터 전송 프로토콜은 이러한 서비스 추상화를 구현해야한다.

신뢰성 있는 데이터의 전송

호스트는 서버로 데이터를 보내면서 신뢰성을 가지고 데이터가 도착할 것이라는 믿음을 가진다.

하지만 네트워크 층 아래의 계층에는 데이터가 손실, 손상, 순서보장 등이 되지 않음을 보장해주지 않는다.

그러므로 transport layer 전송층에서는 데이터의 신뢰성을 보장하지 위해 조치를 취해야한다.

➡️ 신뢰성을 보장해주는 전송층의 프로토콜이 필요

가상의 신뢰성있는 데이터 프로토콜 RDT

두 호스트 간에는 어떻게 데이터가 전달되는 지는 알 수 없다.

신뢰성 있는 데이터 프로토콜을 구축하기 위해 가상의 프토토콜 rdt를 구상해보자

RDT 프로토콜을 이렇게 가정하자

  • 오직 단방향 데이터 전송만을 고려
  • 단 제어 정보는 양쪽방향으로 흐른다

  • 전송자와 수신자의 행동을 유한상태기계 (FSM)를 사용하여 정의할 것이다

RDT 1.0 프로토콜 : 이상적인 채널

RDT 1.0 에서는 아래의 내용을 가정한다.

  • 아래 계층에서 비트에러가 발생하지않는다
  • 패킷의 손실이 발생하지 않는다

먼저 전송자와 수신자의 FSM을 분리하여 생각해보자.

전송자의 경우

  • 윗 계층에서 데이터를 받으면 (rdt_send)
  • 패킷을 udt_send로 보낸다

수신자의 경우

  • rdt_recv 로 패킷을 받으면
  • 데이터를 윗계층으로 올린다

RDT 2.0 프로토콜 : 채널안의 비트 손상

RDT 2.0 에서는 아래의 내용을 가정한다.

  • 아래 계층의 채널에서 비트가 패킷안에서 flip 될 수 있다.
  • ➡️ checksum 을 이용하여 비트 에러를 검출

채널을 신뢰할 수 없다면 오염된 비트를 어떻게 복구 할까?

  • Acknowledgements(ACKs)
    • 수신자는 명시적으로 송신자에게 잘 받았다는 패킷을 보낸다 (ACK)
  • Negative acknowledgements(NAKs)
    • 수신자는 명시적으로 받은 패킷의 오류를 알린다
  • 수신자는 NAK를 받고 패킷을 재전송 Retransmits 한다.

송신자와 수신자의 FSM을 살펴보면 위와 같이 ACK와 NAK를 주고 받으며 신뢰성을 강화한다.

만약 ACK또는 NAK 또한 손상된다면…?

➡️ 3가지 방법이 존재

  • 재질문
    • 또 질문이 왜곡 된다면 더 어렵게 된다
  • 복구 가능한 checksum을 추가
    • 즉각 적으로 문제를 해결할 수 있다
    • 오버헤드가 크다
  • 재전송
    • 현제 데이터 패킷을 단순 재전송한다.
    • 수신자 측에서 중복패킷을 받을 수 있다. (수신자는 중복인지 다음인지 알 수 없다)
    • ➡️ 만약 각 패킷에 번호를 붙인다면 송신자는 중복 패킷을 폐기 할 수 있다.

RDT 2.1 프로토콜 : 순서(0, 1)가 있는 패킷 전송

따라서 RDT 2.1 프로토콜에서는 패킷에 순서 번호를 추가하여 전송하게 된다.

전송자

  • 패킷에 순서(0, 1)를 추가한다.
  • ACK/ NAK 가 손상되었는지 반드시 확인한다.

수신자

  • 받은 패킷이 복제(중복)된 것인지 반드시 확인한다.
    • 순서 0, 1로 추측가능
  • 수신자는 마지막 ACK//NAK가 송신자에게 잘 갔는지 모른다

RDT 2.2 프로토콜 : NAK-free

손상된 패킷이 수신되면 수신자는 NAK를 전송한다.

그 대신에 가장 최근데 정확하게 수신된 패킷에 대해 ACK를 재전송함으로써 NAK를 보낸 것과 같은 효과를 얻을 수 있다. 따라서 NAK를 사용하지 않고 ACK만으로도 손상 패킷 수신을 의미할 수 있다.

따라서 RDT 2.2에서는

  • RDT2.1과 똑같이 작동하지만 오직 ACK만 사용한다.
  • NAK를 사용하는 대신 수신자는 최신의 패킷을 수신하였음에 ACK를 전송한다.
  • ACK를 복제하여 NAK와 똑같은 동작으로 보낸다.

  • RDT2.2 송신자

  • RDT2.2 수신자

RDT 3.0 프로토콜 : 에러와 손실의 채널

RDT3.0 프로토콜에서는 이렇게 가정한다.
하위 채널은 패킷 손실을 고려해야한다. (손상되지 않고 아예 도착하지 않는다)

🤔 사람이라면 어떻게 대응할 것인가…?
➡️ 와야할 대답이 없다면 일단 기다릴 것이다.
➡️ 계속 대답이 없다면 다시 물어볼 것이다.

RDT 3.0 에서는 이렇게 대응한다

  • 합리적인 시간안에 ACK를 받지 못하면 재전송한다.
  • 만약 패킷이 잠시 지연된 것이라면
    • 패킷을 재전송하여 중복이지만, 순서 번호가 있으므로 대처가능하다
    • 그러므로 수신자는 항상 ACK에 번호를 붙여서 보내야한다
  • 합리적인 시간 뒤에 interrupt 하기 위해 타이머를 사용한다.

  • timeout 후 1번 을 보낸다. ➡️ 0번에 대한 응답이 와도 무시한다.
    • 무시하지 않으면 손실된 것인지 지연된 것인지 고려하기가 힘들다
  • 손상되었음을 알아도 타이머를 즉시 끝내지 않고 timeout을 기다린다

  • (b)에서는 pkt1이 손실되어서 ack를 받지 못하자 timeout이 되고 pkt1을 재전송하고 있다

  • (c) 에서는 ACK1이 손실되어 마찬가지로 timeout이 되고 재전송한다
  • (d)에서는 손실된 data가 없지만 짧은 timeout 시간으로 인해 pkt1을 재전송하고 말았다.
    • 중복 수신된 pkt1은 수신자측에서 폐기 되며, 송신자 측에서도 2번째로 온 ACK1을 무시한다.

이제 RDT3.0에는 거의 문제 없이 통신이 가능하다.
하지만 만약 송신자와 수신자의 거리가 멀다면…?

➡️ ACK 응답을 기다리므로 매우 낮은 성능을 보이게 된다.

❓ 🤔 [ 예제 ] 1Gbps 링크, 15ms 전파지연, 8000 비트 패킷
➡️ 전송 지연 시간은 8ms

효율이 0.027% 밖에 나오지 않는다.

➡️ 매우 비효율적이다…. 그렇다면 어떻게 이를 해결할 수 있는가???

 

파이프 라이닝을 한다면 효율을 훨씬 좋게 할 수 있다.

  • 전송자는 ack를 받기 전에 복수개의 패킷을 보낼 수 있다.

계산 해보았을 때 효율이 약 3배 증가한 모습을 볼 수 있다!

그렇다면 어떻게 파이프 라이닝을 구현할 수 있을까?

 

다음 포스팅에서 그 구체적인 방법에 대해 알아보도록 하자

728x90