오래 못 할 짓 하지 않기

[ 네트워크 ] 12. Transport layer : UDP(3) - Reliable Transfer 본문

3학년 2학기/네트워크 (Network)

[ 네트워크 ] 12. Transport layer : UDP(3) - Reliable Transfer

쫑알bot 2024. 10. 10. 18:03
728x90

rdt 3.0 에서 Performance를 생각해보자.

Sender가 보내는 데이터에 대해 Utilization 을 생각해보면

Time to transmit packet을 생각해보면 

 = 보내는 양 / Link Capacity 

 

 

 

 

 

근데 우리는 Stop and wait 방식을 사용하기 때문에 Diagram으로 흐름을 보면 다음과 같다

위에서 구한 정보들을 생각해본다면

사용률이 그닥 높지 않다. 

➡️ 시간은 많이 쓰면서 Stop-and-wait이라서 하나의 packet만 주고받기 때문이다.

 

 

 

📌 해결법

: Pipelining

= Sender는 여러 개의 Packet이 먼저 전송되는 걸 허용한다.

  아직 이전 패킷이 ACK 받지 않아도 우르르 먼저 간다.

  - Sender : Data Packet을 먼저 보내고 , Receiver가 보내는 ACK에 따라 다시 보내줄지 정한다.

  - Receiver : 들어오는 패킷들을 보면서 ACK 을 차례로 보내준다.

 

필기⬇️

packet 하나하나 주고 받는 게 아니라
그냥 다 쪼개서 한 번에 보내고 (Sender)

그렇게 받은 여러 개를 다시 ACK를 다 보내준다. (Receiver)

ACK 받는 걸 기다리기엔 너무 오래 기다려야 함

 

 

위 방법으로 한 번에 3개의 패킷을 전송하여 활용도를 올린다고 생각해보자.. 

같은 [ RTT + L/R ] 시간동안 3배를 더 보낼 수 있기 때문에

활용도 측면에서 큰 이점이 있다.

 


전송 과정에서 Sender가 UnACK를 처리하는 방법에는 두 가지가 있다.

 

1) Go-Back-N  

2) Selective Repeat 

 

 

Go-Back-N  

 

📌 Sender

 

- Window라는 범위를 지정하는 곳 안에 N개의 패킷이 있다.

- 보냈지만 && ACK 응답 확인이 안 된 패킷Window의 base (가장 낮은 순번,왼쪽) 두고,
- Window 내에서 아직 전송이 안 된 패킷 중에 가장 순번이 빠른 놈을 nextseqnum로 둔다.

- timer는  보낸지 가장 오래 된 놈을 기준으로 함.

 

⚫️ Cumulative ACK:  ACK(n) : n번 패킷까지는 전부 다 ACK이고 받음.

     ex) ACK(10) : 10번 패킷까지 다 ACK 받았음.

 

⚫️ Timeout(n) =  n 부터 그 이상 seq인 window에 있는 패킷들을 다시 보내야한다.

      ex) 쎄빠지게 7까지 다 보냈는데, Timeout(3)이면 3부터 7까지(그 이후까지도) 다시 다 보내야 함

 

 

 

12시 방향에서 시작한다.

 

1. condition

 : App 층에서 데이터를 보냄

 

 ➡️ event

       if.  아직 보낼 패킷이 남았으면.

       >  안 보낸 패킷 중에 가장 순번 빠른 애를 만들어서 보내기

               if 이게 첫 패킷이면

                 > 타이머 On

       다음 seq 패킷으로

 


2. condition 

 : timeout이면

 

 ➡️ event

   다시 보냄

 

 


3. condition 

 : 받은 패킷이 corrupt되지 않았다면

 

 ➡️ event

Window에서 Base를 한 칸 옮긴다.

 

if 옮긴 곳이 nextseqnum과 같다면, 즉 모든 데이터를 다 보냈다면

    > 타이머 멈춤

else 

   > 타이머 ON

 

 

 

Base와 nextseqnum이 같은 경우는

1) 가장 처음 전송을 시작할 때

2) 마지막 Data까지 다 보냈을 때

 


📌 Receiver

: 항상 가장 높은 in-order seq #에 대해서만 ACK를 보낸다.

 

위 그림같은 경우에 9번 pkt이 the highest 이다.

Receiver는 9번 이상의 다른 패킷을 받아도

in order하게 받아야 할 10번을 받지 않았다면

ACK를 계속 9로 보낸다.

 

이를 위해서 rcv_base를 지정해둔다.

받아야 하는 seq를 항상 가리키고 있음.

 

올바른 순서로 오지 않았을 땐 어떻게 할지 취향차이이다.

- Buffer에 저장

- Discard

전체적으로 흐름을 보면 아래와 같다.

 

 

 

 


 

Selective Repeat

Go-Back-N 구조에선 2가 삑나면 3,4,5도 못 받는( Discard 되는 ) 구조였음

Selective는 3,4,5 그대로 받고 3,4,5로 ACK를 보냄

그걸 [ Sender에선 ACK받은 기록 ] 과 [ Receiver는 패킷을 정해진 위치에 저장 ]


그런 뒤에 UnACKed Packet만 다시 보냄 = 2packet만 다시

 

 

 

- 순서에 안 맞게 들어오면 버퍼에 일단 담아둔다.

- 하지만 그에 대한 ACK는 그대로 보내고 Sender는 이를 기록한다.

- Loss된 패킷은 ACK를 기다리는 시간이 지나서 다시 Send한다.

 

 

Sender Window는 ACK가 와야 움직이고

Receiver Window는 Received일때 움직인다.

https://github.com/IT-Book-Organization/Computer-Networking_A-Top-Down-Approach/tree/main/Chapter_3/3.4%20신뢰적인%20데이터%20전송의%20원리

이걸 더 자세히 보는 게 도움될 것 같다.

https://ddongwon.tistory.com/81

 

 


Dilemma of Selective Repeat

- Seq의 구성 : 0,1,2,3

- Window의 크기 : 3

 

 

Sender쪽에서 Loss가 날 땐 문제가 없다.

Sender가 보내고 Loss가 나더라도

Window가 변하지는 않기 때문에

 

근데 Receiver Window가 바뀌고 ACK를 보낼 때 Loss가 나면 곤란하다

Sender는 첫번째 Cycle window의 0을 재전송하려고 하지만

Receiver는 두번째 Cycle window의 0을 받으려고 하기 때문에 문제가 된다.

 

⬇️필기

ACK이 도착 안 해서 
Sender가 window를 안 옮겼는데
'Receiver window는 옮김.'

Sender는 1번 사이클 window에 대한 ACK를 기다리는데

이렇게 가다가는
'Receiver는 2번 사이클 window에 대한 ACK'를 보내버릴 수 있다.

 

 

해결법

➡️ Window와 Seq 의 개수 사이의 관계를 잘 맞춘다.

 

Window size  <= size of seq / 2 

 

window의 사이즈는 seq의 개수의 절반 이하여야 한다.

 

 

요약

 

 

(출처)

한동대학교 고윤민교수님 - 컴퓨터 네트워크