[Network] 전송계층1
💻CS/Network

[Network] 전송계층1

728x90
반응형

http://www.kocw.net/home/cview.do?mty=p&kemId=1169634 

 

시작하기 전에 이전 강의 내용을 되돌아보자.

reliable 하다는 것은 pkt error와 pkt loss가 없는 상황을 말한다.

pkt error와 pkt loss는 하위 채널들과 같은 unreliable한 상태에서 발생한다. 

 

각 상황을 해결해줄 수 있는 키워드만을 보자

 

  • pkt error
    • error detection 
    • feedback
    • retransmission
    • seq #
  • pkt loss
    • timeout

이처럼 RDT는 신뢰성 있는 프로토콜을 제공하지만 성능이 별로였다. 왜냐? 1번에 1개의 pkt만 보냈었기 때문!

 

그래서 한 번에 여러 pkt들을 전송해주고 다시 받는 케이스를 지향해야한다. 

그러한 방식들 중에 초기에 등장한 두 가지 방법을 볼 것이다!

 

 

go-back N 

  • Window
    • 하나의 배치 사이즈를 말한다.
    • 윈도우의 크기는 N이라고 한다.
    • N개 만큼 피드백을 받지 않고 일단 한꺼번에 보낸다. 

 

go-back N

초록색 pkt : 이미 receiver에게 ACK 응답을 제대로 받은 상황 즉, 정상적으로 처리된 것

노란색 pkt : sender가 pkt을 보내긴 했으나 아직 ACK 응답을 받지 못한 상태 

파란색 pkt : 가용할 순 있지만 아직 보내지 않은 상태

흰색 pkt : 아직 가용 못함

 

go-back N의 ACK(n)에서 n의 의미 : n번째 pkt까지 잘 받았고, n+1번째를 기다리고 있는 상황

 

하지만 sender가 보내주는 것만 받기만 할 뿐 receiver가 하는 것 없이 멍청한 편이다. 즉 기능을 못한다는 것이다. 

receiver는 그저 자기가 받아야 할 seq #만 보고 기다린다. n개까지 받았으면 n+1만 기다린다는 것이다. 

그럼에 따라 n+1이 아닌 것들은 버리는데, 버린 pkt들은 다시 받을 수 없으며, 다시 그 pkt을 기다리게 되는 상황이 오게 되어 오류를 발생시킨다. (버퍼도 없어 예비로 저장하지도 않는다.)

 

즉 이미 버린 pkt은 다시 받을 수 없는데 그걸 기다리는 상황이 오고 이 때는 계속 ACK(이전)만 뱉는 상황이 오게 된다.  

receiver가 pkt를 버리게 되면..?

receiver가 pkt3을 버린 순간부터 이후 pkt들을 제대로 받을 수가 없게 된다. 

보면 pkt2를 기다리고 있는데 3,4,5가 들어옴에 따라 3,4,5는 버리게 되고 이전까지 잘 받았다는 의미로 ACK1을 계속 뱉게된다.  

그러다 나중에 타임아웃이 되서 pkt2가 들어오면 그제서야 받는다. 즉 pkt2가 안들어오면 3,4,5는 계속 못받게 되는 것이다!

제대로된 ACK가 들어오면 윈도우는 한칸씩 슬라이딩 하는 형태로 진행된다.  

 

유실되면 N개(윈도우 사이즈) 만큼 다시 돌아와 재전송한다 그래서 go-back N이라고 불리는 것임.   

 

지금 보면 유실된건 하나인데 그 하나 때문에 다른 애들도 다 재전송 하고 있다. 윈도우가 작을 때는 무리가 안되지만, 윈도우 사이즈가 커지게 되면 무리가 된다. 

 

결론적으로 보면, 동작은 하지만 뭔가 하나 나사가 빠진 듯한...? 리시버가 아무것도 안해서 샌더가 고생하는 느낌이다. 

 

selective repeat

리시버도 뭐 좀 해야하지 않을까 해서 탄생했다...! 

대신 ACK가 cumulative이면 안되고, 각자 pkt들은 타임아웃을 가진다. 

타임아웃이 되기 전에 ACK를 받으면 자동으로 타임아웃은 해제된다. 

 

go-back N과는 다르게 순서에 맞지 않게 들어오는 것이라도 에러가 발생하는게 아니라면 버퍼에 저장한다. 

 

만약 receiver가 2번을 기다리고 있는 상황에서 3번이 들어왔다면, 3번은 버퍼에 저장시켜두게 되는 것이다. 2번 자리를 채울때 까지 pkt4,5가 들어와도 저장한다. (윈도우 범위까지 / 저장한 것도 제대로 받은 것이니 ACK3,4를 보내줘야 한다.)

selective repeat

pkt0,1까지 잘 받았는데 pkt2를 보내는 과정에서 유실이 된 케이스이다.

pkt2를 기다리는 상황에서 pkt3,4,5가 들어오는데 우선 알맞게 ACK3,4,5를 보내주고 버퍼에 다 저장하게 된다. 

타임아웃이 되어서 pkt2가 들어왔을 때 pkt2만 재전송 해주면, receiver에서는 ACK2를 보내주고, 저장해뒀던 pkt3,4,5를 한 꺼번에 처리한다. (go-back N과 다르게 버리지 않고 저장해뒀기 때문에!)

그리고 나서 pkt2,3,4,5를 application layer에 올려주고 ACK2를 보내준다, 왜냐 최근에 pkt2를 받았기 때문이다!

 

Selective Repeat은 유실된 것만 재전송 해주고,

go-back N은 유실된 것 포함 N개(윈도우 사이즈)를 재전송한다.

 

0 > 1 > 2 > 3 > 4 > 5 > 2 > 6 > 7 > 8 > 9 순서로 진행이 되는 것이다.

이 때 2 이후에는 3,4,5가 스킵되는 것이다. (이전에 저장됐으니, 유실된 패킷만 재전송하여 진행)

리시버가 이제 일을 좀 해야 이렇게 진행이 될 수 있는 것이다. (버퍼에 저장하기만 해도 조금 해결이 되는 것!)

 

하지만 seq #를 고려해줘야한다. seq #는 이전에 봤듯이 헤더의 필더이기에 작을 수록 좋다. 

또한 원하는 건 최소한의 범위를 가진 seq #를 가지고 계속 사용하는 것이 이상적인데, 그 수를 찾는 것은 쉽지 않아보인다. 

아래와 같이 seq # = N + 1로 했을 경우를 보자. 

pkt 0,1,2를 받고 pkt 3을 기다리게 된다. 계속 잘 받았으니 버퍼는 현재 비어있게된다. 

하지만 receiver가 보낸 ACK들이 다 유실될 경우 sender에서는 pkt3을 보내지 못하는 상황이 발생하게 된다.

이에 계속 pkt 0,1,2만 보내게 되고 3번 다음 또 0번이니까 버퍼에 저장해두게 되고 1,2도 마찬가지로 계속 저장만 해두게 된다. 하지만 이건 실제로 duplicate pkt인데 new pkt로 간주하여 문제가 발생하게 되는 것이다!

 

그래서 seq #로는 N+1개를 쓰면 안된다. 그렇다면 seq #를 늘리면 될까?

seq #를 늘리면 해결되긴 한다. (6개 정도로 늘렸을 때 중복 이슈가 해결된다. 하지만 구분할 수 있는 최소 seq #로만 바꾸고 싶을 것이다. 그게 얼마일까? window size와의 관계가 어떨까?)

이에 대략 N x 2정도..?면 충분하지 않을까 싶다. window size와 seq #간에 밀접한 관계가 있는것이다.

즉 중복/새로운 패킷 구분을 하기위해 적절하게 값들을 세팅해 줄 필요가 있다. 

 

하지만 Selective repeat에도 문제가 있는데 그건 바로 모든 윈도우 안의 패킷에 타이머를 걸어야 한다는 것이다. 말만 들어도 문제인 것 같다.. 실제로 윈도우 사이즈가 큰 경우에는 타이머만 걸어주는데 부하가 가서 cpu가 터질수도...있겠다..

프로세스의 개수도 엄청 많아질 경우, 다 tcp 커넥션을 가지고 있으면 다 타임아웃을 갖게되고 난리날 상황이 눈에 훤하다... 

 

그래서 TCP에서는 사실 윈도우를 대표하는 타임아웃을 하나만 두고, ACK도 cumulative로 사용한다고 한다.

이건 다음 시간에 더 알아볼 예정. 

 

아무튼 go-back N 처럼 멍청하게 만들어주지 않도록 + 효율/효과적으로 pkt을 주고받을 수 있게 하기 위해 여러 변화가 있다는 걸 기억하면 될듯하다!

 

728x90
반응형