본 포스팅은 < 컴퓨터 네트워킹 하향식 접근[8판] James F. Kurose, Keith W. Ross 저/최종원, 강현국, 김기태 > 을 참고하여 작성되었습니다.
신뢰성있는 데이터의 전송 : 파이프라이닝
파이프라이닝 : GBN (Go-Back-N) 방법
송신자의 경우
- 초록 : 보내고 응답받음
- 노랑 : 보내고 응답받지못함
- 파랑 : 보낼 수 있지만 보내지 않음
- 하양 : 아직 위에서 데이터를 받아오지 못함
전송자는 window 라는 개념을 이용하여 N개 까지 패킷을 보낸다. (노랑 + 파랑)
- window 란 ACK를 받지 않았더라도 보낼 수 있는 최대 패킷 수이다.
- 앞 쪽 패킷이 ACK를 받으면 슬라이딩 된다.
이 window와 그 동작은 2개의 상태로 관리 할 수 있다.
- send_base : ACK 되지 않은 가장 오래 전에 보낸 패킷 번호
- nextsequnum : 전송 가능한 다음 패킷의 번호 (아직 App으로 부터 받지 않음)
송신자의 경우 3가지 이벤트에 대해 대응해야할 필요가 있다
- rdt_send
- 윈도우가 가득 찼는지 검사
- 괜찮으면 전송 후 변수 갱신
- 그렇지 않으면 버퍼링 또는 오류메세지 전송
- ACK 수신
- 누적 (Cumulative) ACK
- #n 까지의 번호를 붙인 ACK를 패킷에 붙여 보낸다.
- ACK(n)을 받으면 윈도우 시작점을 (N+1) 만큼 옮긴다
- 누적 (Cumulative) ACK
- Timeout 시간초과
- 타이머는 가장 ACK 받지 않은 처음에 보낸 패킷을 기준으로 설정한다
- timeout(n)이 발생하면 윈도우의 가장 높은 순서의 패킷부터 재전송
수신자의 경우
수신자는 오직 ACK만을 응답한다. 타임아웃이 나면 응답을 받은 다음 패킷부터 다시 전송한다.
- EX) < 0, 1, 3, 4 > 를 받았다면 < 0, 1, 1, 1 > 의 순서로 ACK를 전송
- 순서에 맞지않은 패킷은 저장해두지 않는다.
수신자는 제대로 받은 패킷의 ACK를 송신자에게 전송한다.
- 실제 TCP에서는 일정 주기로 받은 패킷까지 ACK 보냄
- 다수의 중복 ACK가 발생하게 됨
- 그러므로 수신자는 어디까지 제대로 받았는지의 상태를 알고 있어야한다.
- ➡️ 수신자는 제대로 받은 곳 까지 되돌아가 (Go-Back-N) 다시 수신받게 된다.
2번 ACK를 받지 못하면 그에 대한 타이머가 timeout된다!
➡️ 받은 3, 4, 5의 패킷은 폐기하고 2번 패킷부터 다시 되돌아가 패킷을 수신하게 된다.
GBN 방식의 경우 윈도우의 크기와 RTT가 높다면 timeout이 나면서 버려지는 패킷들로 인해 성능이 좋지 않을 수 있다. 그렇다면 이를 저장할 수 는 없을까?
파이프라이닝 : SR (Selective Repeat) 방법
SR 방법의 경우 누적 ACK 응답이 아닌 개별적인 ACK 응답을 하게 된다.
EX ) 전송자의 1번 패킷이 손실되어 수신자는 < 0, 2, 3, 4 > 를 받았다면 응답으로 ACK < 0, 2, 3, 4 > 를 보낸다. → 다음 전송자는 빠진 1번 패킷을 포함한 < 1, 5, 6, 7 > 을 전송할 것이다.
전송자는 개별적으로 패킷을 재전송해야함으로 각 패킷에대한 개별적인 타이머가 필요하다.
전송자와 수신자의 window가 다를 수 있다.
전송자의 경우
다음 순서의 패킷이 윈도우안에 전송가능해지면 패킷을 보낸다.
만약 타임아웃 timeout(n) 이 발생한다면,
개별 패킷이 전송되어야 하므로 각 패킷은 자신만의 논리타이머가 필요하다.
수신자의 경우
window 사이즈 ( rcvbase, rcvbase + N -1 ) 내의 패킷 n 이 도착하면 그에 맞는 ACK를 보낸다.
🤔 만약 이미 받은 (초록) 부분의 패킷이 도착한다면 수신자는 어떻게 해야할까?
- 전송자는 ACK를 받지 못한 것이기 ACK 응답을 해주어야한다!!
pk2가 timeout 되고 2번 패킷 개별적으로만 다시 재전송하게 된다. pk3는 버퍼된다.
GBN과 다르게 2, 3, 4, 5를 모두 보내지 않고 2번만 다시 보냄
문제상황 : 🤔 만약 윈도우 크기가 작거나, seq 순서 번호 범위가 작다면…?
window 크기가 3, seq번호가 3번까지인 상황을 가정해보자.
위 그림의 경우 pk0에 대한 타임아웃으로 재전송했지만, 0번이 처음의 0이 아니라 그 다음의 0으로 오해될 수 있다!