2022. 2. 13. 18:23ㆍMajor`/컴퓨터 네트워크
(1) Checksum :: Packet에 오류가 있는지 확인
▶ 송신측
1. 보내려는 세그먼트에서 체크섬을 계산
- 세그먼트 값들을 16비트로 나눠서 각각의 값을 더한후, 1의 보수를 취하면 체크섬이 계산된다
2. 계산된 체크섬 값을 세그먼트의 체크섬 필드에 insert해서 수신측으로 전달
▶ 수신측
1. 수신된 세그먼트의 체크섬 값을 계산한다
- 먼저 체크섬 필드를 0으로 설정하고, 송신측에서 계산하는 것과 동일하게 계산
2. 수신된 세그먼트의 체크섬 필드의 값과 계산한 체크섬 값이 동일한지 확인
- 동일하면 오류 X
- 다르면 오류 O
(2) Acknowledgement / Negative-Acknowledgement :: Packet에 오류가 있는지 없는지 응답해주기
- Receiver가 Sender에게 Packet을 받았다고 응답을 해야 한다
- 이때, 오류를 판별해서 응답 :: 오류 체크 = 체크섬
- "오류 없이 잘 받았다" → Acknowledgement
- "이 Packet에 오류가 존재한다" → Negative-Acknowledgement
(3) Timer
- Packet을 잘 받았으면 Receiver는 Sender에게 잘 받았다고 응답을 해줘야 한다
- Sender가 계속해서 Ack/Negative-Ack를 기다려도 못받으면, "segment가 Drop했구나"라고 생각해서 재전송을 하게 된다
- Timer를 설정해서 기다리는 시간 :: 낭비없이 진행해야 한다
- Timer가 너무 짧으면, Receiver가 잘 받아도, Sender는 재전송을 하게된다
- Timer가 너무 길면, Sender는 계속해서 Ack/Negative-Ack를 기다리기 때문에, segment 에러에 대한 반응이 늦는다
(4) Sequence Number
- Timer가 너무 짧아서, Sender가 재전송을 하게 되는 경우
- Receiver는 Sender가 새로 보낸 Packet을 "받았는지 아니면 새로운건지" 확인을 해야 한다
>> Sequence Number는 해당 Packet의 ID로, Sender가 해당 Packet에 대한 수신 여부를 확인할 수 있다
(5) Window size (rwnd : receive window)
- Sender가 Receiver로부터 Ack/Negative-Ack를 받지 않고 연속해서 보낼수 있는 최대 Data의 양이다
RDT :: Reliable Data Transfer
rdt 1.0 - 신뢰적인 채널 상의 신뢰적인 전송
- 하위 채널에 대해서 전적으로 신뢰한다
- 비트 오류 X / 패킷 손실 X
- 송신자 : 하위 채널에 Data 전송
- 수신자 : 하위 채널로부터 Data 받는다
rdt 2.0 - 비트 오류가 존재
- 하위 채널에서 비트 오류가 발생할 수 있다
- 체크섬을 통해서 비트 오류 검출
▶ 오류 복구
ACK :: Acknowledgement
- 수신한 Packet에 문제가 없다고 Sender에게 알린다
NAK :: Negative - Acknowledgement
- 수신한 Packet에 문제가 존재한다고 Sender에게 알린다
- Sender는 해당 Packet을 재전송한다
▶ rdt 2.0의 문제점
- ACK/NAK 패킷의 오류 가능성 고려 X
ex) ACK/NAK 패킷에 오류가 발생하면
- Sender는 Receiver에게 일어난 상황을 알 수 없다
- 단순히 재전송하게되면, 중복 패킷이 발생하게 된다
rdt 2.1 - 송수신자 ACK/NAK 오류 고려
- 패킷에 Sequence Number를 추가해서 rdt 2.0의 문제점을 해결한다
- (0, 1) 2개의 Sequence Number를 사용한다
- 0, 1을 번갈아서 전달하기 때문에 중복인지 아닌지 판단하는데 2개면 충분하다
송신측 (Sender)
1. 패킷을 보내고 ACK 0 / NAK 0 신호를 기다린다
- 수신측에서 에러 발생 : NAK 0
- 수신측에서 에러 발생 X : ACK 0
2. 다음 패킷을 보내고 ACK 1 / NAK 1 신호를 기다린다
- 수신측에서 에러 발생 : NAK 1
- 수신측에서 에러 발생 X : ACK 1
3. 다음 패킷을 보내고 ACK 0 / NAK 0 신호를 기다린다
4. 계속해서 이러한 과정들을 반복
수신측 (Receiver)
1. 0번 패킷
- 오류 O : NAK 0 신호를 보내고 해당 패킷의 재전송을 기다린다
- 오류 X : ACK 0 신호를 보내고 다음 패킷이 오길 기다린다
2. 1번 패킷
- 오류 O : NAK 1 신호를 보내고 해당 패킷의 재전송을 기다린다
- 오류 X : ACK 1 신호를 보내고 다음 패킷이 오길 기다린다
3. 2번 패킷
- 오류 O : NAK 0 신호를 보내고 해당 패킷의 재전송을 기다린다
- 오류 X : ACK 0 신호를 보내고 다음 패킷의 재전송을 기다린다
4. 계속해서 이러한 과정들을 반복
rdt 2.2 - NAK 없는 프로토콜
- rdt 2.1과 같은 기능이지만, NAK를 없애고 ACK만 사용한다
1. 송신 : 0번 패킷 전송
- 수신 - 오류 O : ACK 1 신호를 보내고 재전송 요구
- 송신측은 ACK 0 신호를 기대했는데, ACK 1 신호를 통해서 오류가 발생했다는 사실을 알고 재전송
- 수신 - 오류 X : ACK 0 신호를 보내고 다음 패킷 요구
2. 송신 : 1번 패킷 전송
- 수신 - 오류 O : ACK 1 신호를 보내고 재전송 요구
- 송신측은 ACK 0 신호를 기대했는데, ACK 1 신호를 통해서 오류가 발생했다는 사실을 알고 재전송
- 수신 - 오류 X : ACK 0 신호를 보내고 다음 패킷 요구
3. 송신 : 2번 패킷 전송
- 수신 - 오류 O : ACK 1 신호를 보내고 재전송 요구
- 송신측은 ACK 0 신호를 기대했는데, ACK 1 신호를 통해서 오류가 발생했다는 사실을 알고 재전송
- 수신 - 오류 X : ACK 0 신호를 보내고 다음 패킷 요구
4. 계속해서 이러한 과정들을 반복
rdt 2.0/2.1/2.2의 결함
- rdt 2.0/2.1/2.2는 패킷 에러에 대해서는 대응할 수 있다
- 그러나, ACK/NAK or 패킷에 중간에 유실되는 경우에는 대응할 수 없다
- 송신 측에서는 ACK 신호를 기다리고 있는데, ACK 신호가 중간에 유실되어서 받을 수가 없는 경우
rdt 3.0
- 송신 측에서 ACK 신호를 특정한 시간동안 기다리고, ACK 신호가 해당 시간내에 오지 않으면 패킷을 재전송
파이프라인 프로토콜 (Pipelined Protocol)
- Sender가 ACK 신호를 받지 않아도 일단 Packet을 여러개 보낼 수 있다
- Sender와 Receiver는 Buffer를 보유하고 있어야 한다
Go-Back-N / Selective Repeat
- GBN : 송신측에만 Buffer 존재
- SR : 송수신측 둘다 Buffer 존재
Go-Back-N (GBN)
- 초록 : Packet을 보냈고 ACK 신호도 받음
- 노랑 : Packet을 보냈지만, ACK 신호는 아직 안받음
- 파랑 : Packet을 아직 안보냄
- 흰색 : 사용할 수 없음 (Window Size가 정해져있기 때문)
송신
- Window Size만큼의 Packet을 보낸다
수신
- Buffer에 Window Size만큼의 Packet들을 저장한다
- 수신측은 누적 ACK (Cumulative ACK)를 사용한다
>> ACK를 받은 패킷은 window에서 제외되고, window size를 채워야 하니까 다른 Packet들의 window로 들어간다
- 각 Buffer가 전송될 때, ACK를 받지 못한 가장 오래된 Packet의 Timer를 기준으로 Timeout이 발생한다
- Timeout이 발생하면 Buffer에 있는 모든 Packet들을 전송한다
- Window Size : 4
1. Packet (1, 2, 3, 4)를 전송한다
- 전송 도중 Packet 2 Loss
- 수신측은 Packet 0, 1을 받았기 때문에, ACK 0, 1을 보내고 Packet 2가 오기를 기다린다
2. 송신측은 ACK 0을 받았으므로 Packet 4를 보낸다
3. 송신측은 ACK 1을 받았으므로 Packet 5를 보낸다
4. 수신측은 Packet 2를 원하고 있는데 Packet 3을 받았기 때문에 가장 최근에 수신 성공한 패킷 1에 대한 ACK 1을 보낸다
5. 수신측은 Packet 2를 원하고 있는데 Packet 4를 받았기 때문에 가장 최근에 수신 성공한 패킷 1에 대한 ACK 1을 보낸다
6. 수신측은 Packet 2를 원하고 있는데 Packet 5를 받았기 때문에 가장 최근에 수신 성공한 패킷 1에 대한 ACK 1을 보낸다
7. 송신측은 아까 ACK 1을 받았기 때문에 3개의 ACK 1 신호를 전부 무시한다
- 송신측은 Packet 2를 보내고 일정 시간이 지나도록 ACK 2를 받지 못했기 때문에 Timeout이 발생한다
8. Timeout이 발생했기 때문에 window의 모든 패킷(2, 3, 4, 5)를 전송한다
>> GBN은 수신측에서 Packet을 못받았을 경우, 송신측에서 해당 Packet부터 전부 다시 재전송한다
- 원하는 Packet이 올 때까지 다른 모든 Packet들을 계속 버리게 된다
- Packet 하나 때문에, 많은 Packet들을 재전송해야 하기 때문에 비효율적이다
Selective Repeat (SR)
- GBN의 비효율성을 해결하기 위한 방식 :: SR
- 송신측은 각 Packet마다 Timer를 설정하고, Timeout된 Packet만 재전송한다
- GBN처럼 하나의 Packet이 Timeout되면, Buffer 내의 모든 Packet을 재전송하지 않는다
- 수신측은 기다리던 Packet이 오면, 바로 상위 계층으로 전달하고, ACK 신호를 보낸다
- 수신측은 기다리는 Packet이 오지 않으면, 일단 Buffer에 넣어두고 ACK 신호를 보낸다
- Buffer가 가득 차면(Packet이 모두 도착) 상위 계층으로 전달한다
- 모든 Packet에 Timer가 존재하기 때문에, 오버헤드가 굉장히 크다
- Window Size : 4
1. Packet (1, 2, 3, 4)를 전송한다
- 전송 도중 Packet 2 Loss
- 수신측은 Packet 0, 1을 받았기 때문에, ACK 0, 1을 보내고 상위 계층에 Packet 0, 1을 전달하고 Packet 2가 오기를 기다린다
2. 송신측은 ACK 0을 받았으므로 Packet 4를 보낸다
3. 송신측은 ACK 1을 받았으므로 Packet 5를 보낸다
4. 수신측은 Packet 2를 원하고 있는데 Packet 3을 받았기 때문에 Packet 3을 일단 Buffer에 넣어두고 ACK 3을 보낸다
5. 수신측은 Packet 2를 원하고 있는데 Packet 4를 받았기 때문에 Packet 4를 일단 Buffer에 넣어두고 ACK 4를 보낸다
6. 수신측은 Packet 2를 원하고 있는데 Packet 5를 받았기 때문에 Packet 5를 일단 Buffer에 넣어두고 ACK 5를 보낸다
Packet 2에 대한 Timer가 Timeout되었기 때문에 송신측은 Packet 2를 다시 보낸다
7. 수신측은 Packet 2까지 받고, Buffer에 존재하는 Packet(3, 4, 5)를 포함해서 Packet 2, 3, 4, 5를 상위 계층에 전달하고 ACK 2를 보낸다
>> SR은 동일한 순서번호를 가진 Packet이 존재할 경우 :: 수신측은 중복된 Packet을 받는 문제가 발생할 수 있다
- Window Size를 Sequence Number 크기의 절반보다 작거나 같게 설정하면 문제를 해결할 수 있다
- Window Size ≤ (Sequence Number Size)/2
- 위의 예시를 보면 Window Size는 9/2 :: 4보다 작거나 같으면 된다