
rdt 3.0은 정확했지만 느렸습니다. 패킷 하나를 보내고 ACK가 올 때까지 손 놓고 기다리기 때문입니다. RTT가 100ms인 회선에서 이렇게 하면 링크 용량이 아무리 커도 대부분의 시간을 대기에 씁니다. 이번에는 그 낭비를 없애면서도 신뢰성을 유지하는 두 가지 방식을 알아보겠습니다.
해법은 단순합니다. ACK를 기다리지 않고 여러 패킷을 연달아 보내는 것입니다. 다만 무한정 보낼 수는 없습니다. 재전송에 대비해 보낸 것을 들고 있어야 하고, 받는 쪽도 감당할 수 있어야 하기 때문입니다.
그래서 "확인받지 못한 채 떠 있어도 되는 패킷 수"에 상한을 둡니다. 이것이 window size(윈도우 크기)이고, 보통 N으로 씁니다. 윈도우는 ACK가 도착할 때마다 앞으로 미끄러집니다.

sequence number의 범위도 1비트로는 부족해집니다. 떠 있는 패킷이 여러 개이므로 그들을 전부 구분할 수 있어야 합니다.
윈도우를 쓰는 방식은 크게 둘로 갈립니다. 잃어버린 패킷 하나 때문에 뒤엣것까지 모두 다시 보내느냐, 잃어버린 것만 골라 보내느냐입니다.
GBN(go-back-N)의 규칙은 세 가지입니다.

수신 측이 버퍼를 갖지 않아 구현이 단순합니다. 대신 하나 잃었을 뿐인데 멀쩡히 도착했던 pkt2와 pkt3까지 버려지고 다시 전송됩니다. 윈도우가 크고 오류가 잦을수록 손해가 커집니다.
SR(selective repeat)은 그 낭비를 없앱니다.

| go-back-N | selective repeat | |
|---|---|---|
| 역할 | 순서대로만 받고 어긋나면 되돌아감 | 어긋난 것도 받아두고 빈칸만 채움 |
| 신뢰성 | 동일하게 보장 | 동일하게 보장 |
| 오버헤드 | 재전송 낭비가 큼. 수신 버퍼 불필요, 타이머 1개 | 재전송 최소. 수신 버퍼 필요, 타이머 N개 |
| 쓰이는 곳 | 오류가 드물고 윈도우가 작을 때 | 오류가 잦고 대역폭이 아까울 때 |
SR에는 함정이 하나 있습니다. sequence number는 유한해서 결국 돌아옵니다. 그런데 송신 측 윈도우와 수신 측 윈도우가 같은 시점에 서로 다른 구간을 보고 있을 수 있습니다.
번호 공간이 0~3이고 윈도우 크기가 3인 경우를 보겠습니다.
수신 측은 두 경우를 구분할 방법이 없습니다. 패킷에는 번호만 적혀 있고 그 번호는 재사용되기 때문입니다. 이를 막으려면 윈도우 크기가 번호 공간의 절반 이하여야 합니다. 위 예에서 번호가 4개이므로 윈도우는 2 이하여야 안전합니다.
일반화하면 k비트 sequence number를 쓸 때 윈도우 크기는 2^k / 2 이하입니다. 송신 윈도우와 수신 윈도우가 절대 겹치지 않도록 번호 공간을 넉넉히 두는 것입니다.