등장 배경
Reliable 하게 전송을 하기 위해서는 패킷을 보내고 잘 받았는지 ACK 응답을 받아야 한다.
하지만 ACK 을 받고 다음 패킷을 전송하려면 stop-and-wait
문제가 발생하게 된다.
패킷을 실제 전송하는데는 시간이 거의 걸리지 않지만,
패킷이 네트워크를 타고 목적지까지 갔다가 ACK 신호를 가지고 돌아오는데까지 걸리는
RTT
(Round Trip Time : 왕복시간) 가 너무 많이 걸리기 때문에
ACK 신호를 받고 다음 패킷을 보내는 것은 사실상 어렵다.
이를 극복하고자 나온 것이 Pipelined protocol
!
Pipelined protocol
pipelined protocol 에서 사용하는 방법은 두 가지가 있다.
- go-Back-N
- selective repeat
Go-Back-N
cumulative ACK : 예를들어 8번 패킷에 대한 ACK 이 오면?
1~7 은 다 잘 받았구나 ! 하고 간주하는 방식
그림에서 초록색 부분은 이미 다 받았다고 ACK 이 온 데이터.
window size 는 상대가 가지고 있는 버퍼 크기에 기반,
데이터를 전송할 수 있는 최대 사이즈 라고 생각하면 된다.
노란색은 보내긴 했지만 아직 ACK 이 오지 않은 데이터,
파란색은 아직 보내지 않은 데이터이다.
ACK 이 올때마다 window size 는 점점 오른쪽으로 옮겨갈 것이다.
만약 window size 만큼 데이터를 보냈는데 전부 ACK 을 받지 못했다면
window size 안의 패킷들은 다 노란색으로 차게 된다.
go-Back-N 방식이나 selective repeat 모두 위 그림처럼 보낸다.
다만 잘 전송되지 않았을 때 방식이 다른데 go-Back-N 부터 확인해보자.
위 그림에서 window size 는 4 이므로 sender 는 4개의 패킷을 보낸다.
receiver 가 0,1 번 패킷은 잘 받았는데 2번 패킷이 loss 났을 때
go-Back-N 방식에선 3번 패킷부터 discard 한다.
그리고 receiver 는 다른 패킷을 받아도 다 버리고, 1번 패킷을 잘 받았다는 ack 신호를 계속 보낸다.
아직 2번 패킷을 받지 못했기 때문에 2번을 달라고 sender 에게 알리는 것 !
sender 입장에서는 ack0 을 받으면 buffer 에서 0번 패킷은 날리고 (성공적으로 전송된 것이니까)
window 를 한칸 오른쪽으로 옮기고 4번 패킷을 보낸다.
ack1 을 받으면 역시 동일하게 동작하고 5번 패킷을 보낸다.
그리고 ack1 을 receiver 로부터 중복해서 수신하게 되는데,
sender 는 일단 이 중복 ack 을 무시한다.
그러다가 timeout 이 나면 패킷 2,3,4,5 를 재전송한다.
이게 바로 go-Back-N 방식 !
여기서 N 은 2번일 것이다.
2번 패킷이 loss 났기 때문에 2번 패킷으로 다시 가서 재전송하는 방식.
Selective repeat
cumulative 하게 ACK 을 받는 것이 아니라 individually 하게 ACK 을 받는다 !
즉 10개의 패킷을 보내면, 10개 각각 ACK 을 받아야 모두 잘 전송되었다고 간주하는 방식.
만약 ACK 이 안 온 패킷이 있다면 해당 패킷만 다시 보내자 !
아까 그 그림에 빗대어 생각해보자.
초록색은 ACK 이 온 패킷, 노란색은 아직 ACK 이 오지 않은 패킷일 때
timeout 이 발생하거나 패킷 하나만 전송이 실패했을 때
해당 패킷만 재전송하는 방식이다.
똑같이 2번 패킷에서 loss 가 났다고 했을 때,
Selective repeat 은 2번 패킷만 보내는 방식 !