
RDT (Reliable Data Transpose) 는 sender 와 reciever 의 feedback , retransmission 으로 이뤄진다.
feedback 에 맞춰 sender 는 retransmission 하고, 중복된 데이터에 대해서는 packet에 부여된 sequence number 를 가지고 reciever 가 알아서 처리한다.
만약 loss 가 일어나 feedback 없을 경우엔 feedback 이 오기 까지의 timer 를 설정하여 feedback이 없으면 retransmission

L : 데이터의 길이 (비트 또는 바이트 단위)R : 데이터 전송 속도 또는 비트 전송률 (bps 또는 b/s 단위)L/R : 데이터 길이 / 데이터 전송 속도 ==> 데이터 전송 시간RTT : Round Trupe Time ==> sender 가 마지막 비트를 전송하고 receiver 가 마지막 비트 까지 수신, 피드백을 sender 가 받을 때 까지 걸리는 시간 (L/R)/(RTT+L/R) : 전체 지연 시간 으로 데이터를 전송하는데 걸리는 시간을 전체 왕복 시간으로 나눈 값으로, 네트워크에서의 전체 지연 시간을 나타낸다. ==> 그러니 RDT 는 유실 없이 신뢰도 높은 데이터 전송 프로토콜이지만 feedback 을 받기 까지의 RTT 라는 시간을 소모하기 때문에 많은 시간이 소모 된다.
하지만 packet 을 하나씩 보내고 feedback 을 받기 보다 우루루 보낸 후 feedback 을 받으면 ?

어차피 RTT 는 데이터를 몇 개씩 연속으로 보내든과 상관 없이 일정하다.
똑같이 3개의 packet 을 보낼 때 하나씩 수신하고 확인 할 필요 없이 우루루 보내는게 시간이 훨씬 빠르다.
그래서 실제 생활에서는 하나씩 보내고 피드백을 수신하는 방식이 아닌
우루루루루 보낸다.
그럼 우루루루 보내는데도 어떻게 신뢰성 있는 데이터 전송을 만들게 할까 ?
window size : 윈도우 사이즈만큼은 피드백을 받지 않아도 packet 을 우수수수 보내자.Ack(n) : cumulative ACK 로 n 까지의 ACK 를 누적 (n 번째 ACK 가 아님)Reciever 는 순정파만약 내가 0번 ~ 3번 까지의 packet 을 리시버한테 보낸다고 해보자
만약 유실이 없으면
packet 1 전송 -> ACK 1 feedbackACK1 받아서 packet 2 전송 -> ACK 2 feedbackACK3 받아서 packet 4 전송 -> ACK4 feedback 된다.
그러니까 리시버는 packet1 을 받았으면 ACK1 을 피드백 하고 다음 패킷인 packet2 만을 기다린다.
만약 내가 ACK1 인 상태에서 packet2 를 제외한 다른 packet을 받으면 그냥 안받고 여전히 packet2 내놓으라고 ACK1 을 유지한다.
만약 유실이 있거나 packet 의 전송 속도가 달랐다고 해보자
sender 는 0 , 1, 2 , 3 , 4 , 5 , 6 , 7 packet 을 갖고 있고 window size : 4 라고 해보자
그니까 sender 는 피드백을 받건 말건 4개의 packet 을 우루루루 보내겠다는 거다.
GBN in ACTION
0 , 1 , 2 ,3우루루 방출
- receiver 의 ACK 상태 변화
0받고ACK0=>1받고ACK1=>2못받아서 여전히ACK1=>3받아도 여전히ACK1sender는0,1,2,3을 보냈지만 사실상receiver는0,1만 받은 상태sender는window에 맞춰서4,5,6,7우루루 방출
sender: "어 ~ 너가ACK몇 번을 보내든 난 윈도우대로 보낼거야 ~"- 우루루 방출해도 리시버는 안받는다.
receiver: "나는ACK1이고packet 2내놔, 너가 뭘 보내도 나는 안받고ACK1만 대답할거임 "packet2에 대한 피드백이 올 때 까지 너무 시간이 오래 걸리니sender측의 타이머가 터진다. (timeout)sender정신 차림
sender: "아 윈도우 다시 구성해서 보내야겠다. 어차피 2번 안받았으면 여태 보낸 것들도 못받았을거 아냐 "2,3,4,5로 윈도우 다시 구성하고 재전송
왜 이름이 Go Back N 인가욜
윈도우 사이즈가 N 일 때 , 뭔가 타이머가 터지면 문제가 터진 부위로 되돌아가서 N 개 만큼의 윈도우로 다시 보내셈요 ㅋㅋ
sender 는 윈도우 전에 있던 놈들은 가지고 있을 필요가 없음sender 가 0 , 1 , 2 , 3 , 4 , 5 ,6 , 7 ,8 ,9 를 가지고 있고 window : 4 인 상태에서
현재 우루루 쏟아붓고 ACK5 를 받았다고 해보자
그럼 sender 는 6 , 7 , 8 ,9 의 윈도우를 구성해서 우루루 쏟으면 된다.
ACK5 라는 뜻은 receiver 는 ACK1 , 2 , 3 ,4 , 5 까지 했다는 거니까
packet 0 ,1 , 2 , 3 , 4 , 5 는 잘 전송이 된거다.
그러니까 sender 는 packet 0 ~ 5 는 가지고 있을 필요 없다.어차피 보냈으니까
내가 윈도우 사이즈에 맞게 우루루루 packet 을 보냈는데 그 중 하나라도 유실되면 다시 그 사이즈부터 윈도우를 구성하고 우루루루 packet 을 보내야 한다.
만약 window 사이즈가 100이라고 해보자
내가 우루루루루 쏟아부었는데 그 중 packet 1 이 유실되었다고 가정해보자
sender 는 0 ~ 99 쏟아붓고 100 ~ 199 쏟아 붓던 도중 packet1 유실 타이머가 터지면 다시 1 ~100 으로 윈도우를 구성하고 또 쏟아부어야 한다.
이미 난 1~99 까지 보냈는데 또 보내야 한다. 나는 보냈지만 sender 가 안받아버려서 중복된 패킷을 또 보낸다.
Selective Repeat:GBN너 가능성 있어 , 열심히 해![]()
리시버는 정확하게 받은 packet 에 대해서는 정보를 담고, 올바른 packet 에 대해선 ACK 를 보낸다.
예 :
0 , 1 , 2 ,3을 보냈고 그 중0만 유실된 상황
receiver:[empty , 1 , 2 , 3]으로 패킷을 받고ACK 1 ~ 3은 보낸다.
센더는 받지 않은 ACK 에 맞는 packet 만을 재전송 한다.
sender:ACK 1 ~3은 받았고 ..ACK0이 없네 ==>packet 0재전송
Selective Repeat 에서는 receiver 도 packet 을 저장할 buffer 가 존재한다.
sender 의 window size 에 맞춰 receiver 도 buffer를 준비해준다.
Selective repeat 과정위 과정을 이해해보자
초기 전송
window size : 4
sender 0 , 1 , 2 , 3순차적으로 보내고receiver의buffer는[0의 공간, 1의 공간 , 2의 공간 , 3의 공간]를 기다리고 있음
0도착 완료 =>ACK 0보내고receiver의buffer이동[1의 공간, 2의 공간 , 3의 공간 , 4의 공간]
1도착 완료 =>ACK 1보내고receiver의buffer이동[2의 공간, 3의 공간 , 4의 공간 , 5의 공간]
2유실되고3도착 완료 =>ACK3보내고receiver의buffer[2의 공간, 3 채워짐 , 4의 공간 , 5의 공간]
sender4,5,6,7순차적으로 보냄
4도착 완료 =>ACK4보내고receiver의buffer[2의 공간, 3 채워짐 , 4 채워짐 , 5의 공간]
5도착 완료 =>ACK5보내고receiver의buffer[2의 공간, 3 채워짐 , 4 채워짐 , 5 채워잠]
2유실 된 것에 대한time out터져서sender는2 다시 보냄=>2도착 완료 =>ACK2보내고receiver의buffer[2채워짐, 3 채워짐 , 4 채워짐 , 5 채워잠]다시 재 전송된 후의 움직임
receiver는2받았으니까buffer[6 공간 , 7공간 , 8공간 , 9공간]으로buffer형성하고 기다림
sender는ACK2받았으니까 윈도우[3,4,5,6]으로 만들어둠
근데 이미ACK3 , 4 , 5는 받았으니[3,4,5,6]로 윈도우 구성했다가
-sender: 어 ?ACK3있네 ? ==> 윈도우 재구성[4,5,6,7]
-sender: 어 ?ACK4있네 ? ==> 윈도우 재구성[5,6,7,8]
-sender: 어 ?ACK5있네 ? ==> 윈도우 재구성[6,7,8,9]
마지막ACK가ACK5니까[6,7,8,9]우루루 전송
seqeumce number 는 작을 수록 좋다 . header 에 들어가는데 보내야 할 packet 이 1억개라고 header 에 0 ~ 1억 -1 까지의 번호를 하나하나 세겨놓으면 자원 낭비가 심하니까
그럼 내가 윈도우 사이즈를 3으로 지정해두고 sequence number 는 0 , 1 , 2 , 3 으로 구성해뒀다고 해보자
내가 데이터가 몇 개가 있든
0 , 1 , 2 , 3 , 0 , 1 , 2 , 3 ....이런식으로 번호를 지정하겠다는 거임
만약 sender 가 첫 번째 윈도우인 0,1,2 보냈고 receiver 는 모두 잘 받아서 receiver 의 버퍼는 다음 윈도우의 [3 , 0 , 1] 을 기다리고 있을거다.
첫 번째 전송 후 sender 는 다음 윈도우인 [3 , 0 , 1] 을 보내겠지
그러면 [3 , 0 , 1] 에서 3 은 잘 받았어
그리고 timer 가 터져서 sender 는 ACK0 , 1 , 2 가 없으니 첫 번째 윈도우인 [0 , 1 ,2 ] 를 다시 보낼 것앋.
이 때 발생하는 문제는 recevier 버퍼 안에 다음 윈도우인 [3 , 0 , 1] 을 기다리는데 0 , 1 이 들어왔으니 recevier는 다음 윈도우의 0 , 1 인줄 알고 냅다 받아버린다. (2 는 자리가 없으니까 그냥 안받아버림)
다 차면 윈도우 이동하고 2 에 대한 ACK 없으니 재전송하고 ..
그럼 리시버는 전 윈도우의 2 지만 현재의 2 인줄 알고 받아버리고 ..
그러면서 악의 순환 고리 ...
그럼 어떻게 해결할까 ?
시퀀스 넘버를 윈도우 사이즈의 2배로 해보자
요렇게 ==>
0 , 1 , 2 , 3 , 4 , 5, 0 , 1 , 2 , 3 , 4 , 5 , 0 , 1 , 2 , 3 , 4 , 5 ..
sender : [0 , 1 ,2 ] 전송 => recevier 전부 잘 받고 buffer : [3 , 4 ,5] 주세요 , 현재 ACK는 2 ACK 0 , 1 ,2 유실됐으니 sender 는 [0 , 1 ,2 ] 재전송receiver : 어 ~ 버퍼에 자리 없으니까 안받아 3내놔 ~ sender 는 다음 윈도우인 [3,4,5] 보냄recevier 는 ACK5 보내고 [0,1,2] 기다림sender : 엥 왜 아직도 ACK 0 , 1 ,2 가 안오징 .. 재전송 해야하나 .. 고민함 recevier 가 ACK5 보냈으니 [0,1,2] 내놓으라고 닥달함 sender 는 ACK5 받았으니 이전에 윈도우인 0,1,2,3,4,5 애들은 무시하고 다음 윈도우를 구성 [0,1,2] 하고 보냄sender 는 ACK 0 , 1 ,2 받았으니 만족그럼 도대체 시퀀스 넘버는 윈도우 사이즈의 몇배로 해야할까 ?
그건 다음 강의에 ..