전송 계층에서의 신뢰적인 데이터 전송(rdt)이 이루어지는 과정을 FSM을 이용하여 단계별로 표현한다.
rdt 1.0 (하위 채널이 완전히 신뢰적인 경우)
하위 계층이 완전히 신뢰적이다는 것은 Sender, Receiver 간 패킷을 전송하는 과정에서,
패킷의 데이터가 깨지거나 패킷이 손실되지 않는다는 의미다.
하위 계층이 완전히 신뢰적이면 전송 계층에서 패킷을 검증하는 과정을 수행할 필요가 없다.
FSM 상세 설명은 다음과 같다.
초기 상태 : 상위 애플리케이션 계층으로부터 데이터를 받기 위해 대기한다.
Sender
① 상위 계층의 프로세스로부터 데이터가 도착한다.
② 전송 계층에서 전달받은 데이터로 패킷을 만든다.
③ 전송 계층에서 생성한 패킷을 하위 계층으로 전달한다.
Receiver
초기 상태 : 하위 계층으로부터 패킷이 올 때까지 대기한다.
④ 하위 계층으로부터 전송 계층으로 패킷이 도착한다.
⑤ 전송 계층에서 패킷으로부터 데이터를 추출한다.
⑥ 추출한 데이터를 상위 계층 프로세스로 전달한다.
rdt 2.0 (하위 채널에 비트 오류가 있을 경우)
rdt 2.0 rdt 2.x는 Sender, Receiver 간 패킷을 전송하는 과정에서,
전송 계층의 하위 채널에서 데이터가 깨질 가능성이 있는 경우를 고려한다.
단, 패킷은 반드시 Receiver에게 도착한다.
checksum을 통해 데이터 오류를 검증하고, ACK 또는 NAK를 이용해 에러 여부를 확인한다.
Sender의 동작을 FSM으로 표현하면 다음과 같다.
Sender
초기 상태는 상위 계층으로부터 데이터를 받기 위한 대기 상태다.
① 상위 계층의 프로세스로부터 데이터가 도착한다.
② 전송 계층에서 전달받은 데이터와 checksum으로 sndpkt(전달할 패킷)을 만든다.
③ 전송 계층에서 생성한 패킷을 하위 계층으로 전달한 다음 ACK, NAK를 받기 위해 대기하는 상태로 변환한다. 이 떄 Receiver로부터 ACK를 받을 때까지 sndpkt를 보관한다.
④ 만일 Receiver로부터 rcvpkt을 전달받았고, 그 패킷이 NAK면
⑤ sndpkt을 재전송한다.
⑥ 또는 Receiver로부터 rcvpkt을 전달받았고, 그 패킷이 ACK면 상위 계층으로부터 데이터를 받기 위해 대기하는 상태로 변환한다.
Receiver
초기 상태는 하위 계층으로부터 데이터를 받기 위해 대기중인 상태다.
① 하위 계층으로부터 rcvpkt가 도착하였고, 데이터가 깨지지 않았다면
② rcvpkt로부터 data를 추출하여 상위 계층으로 전달하고, ACK를 하위 계층으로 전달한다.
③ 만일 하위 계층으로부터 rcvpkt가 도착하였고, 데이터가 깨진 상태라면
④ NAK를 하위 계층으로 전달한다.
rdt 2.1
rdt 2.0에는 ACK, NAK가 망가질 수 있다는 치명적 결함이 있다.
Receiver가 보낸 패킷(ACK 혹은 NAK)이 망가졌을 경우,
Sender는 망가진 패킷이 ACK인지 NAK인지 확인할 수 없으므로 패킷을 무조건 다시 보낸다.
Receiver 측에서는 보냈던 패킷이 NAK였으면 손상된 패킷을 다시 받을 수 있으므로 문제가 없지만,
ACK였으면 같은 패킷을 중복해서 받게될 수 있다.
따라서 패킷의 중복 여부 확인을 위해 Sender 측에서 Sequence Number를 패킷에 추가해야 한다.
다만, 이전에 보냈던 패킷과의 중복 여부만 확인하면 되므로 Sequence Number는 0 혹은 1이다.
Sender의 동작 과정을 FSM으로 표현하면 다음과 같다.
초기 상태는 seq num이 0인 패킷을 만들기 위해 상위 계층으로부터 데이터를 기다리는 상태다.
① 상위 계층의 프로세스로부터 데이터가 도착한다.
② 전송 계층에서 전달받은 데이터에 sequence number 0과 checksum을 추가해 sndpkt을 만든다.
③ 전송 계층에서 생성한 패킷을 하위 계층으로 전달한 다음 0번 패킷에 대한 ACK, NAK를 받기 위해 대기하는 상태로 변환한다. 이 떄 Receiver로부터 ACK를 받을 때까지 sndpkt를 보관한다.
④ Receiver로부터 rcvpkt을 전달받았을 때, 패킷이 깨졌거나 NAK인 상황이라면
⑤ sndpkt을 재전송한다.
⑥ 또는 Receiver로부터 rcvpkt을 전달받았을 때, rcvpkt가 깨지지 않았고 ACK면,
상위 계층으로부터 데이터를 받아 seq num이 1인 패킷을 만들기 위해 대기하는 상태(wait for call 1 from above)로 변환한다.
이후 seqence number를 바꾸어가며 ① ~ ⑥ 과정을 반복한다.
한편, Receiver의 동작과정은 다음과 같다.
초기 상태는 하위 계층으로부터 seq num이 0인 패킷을 받기 위해 대기하는 상태다.
이 때 Receiver의 동작은 ①②③, ④⑤⑥, ⑦⑧의 세 그룹으로 나뉜다.
① 하위 계층으로부터 rcvpkt가 도착하였고, rcvpkt가 손상되었다.
② NAK와 cksum으로 이루어진 sndpkt를 만든다.
③ 하위 계층으로 sndpkt을 전달한다.
④ 손상되지 않았고, seq num이 1인 rcvpktrk 하위 계층으로부터 도착하였다.
⑤ ACK와 checksum으로 이루어진 sndpkt를 만든다.
⑥ 하위 계층으로 sndpkt을 전달한다.
이 때 전달받은 패킷의 seq num이 0이 아니므로 패킷은 버린다.
Sender가 다른 seq num의 패킷을 보냈다는 것은 Receiver가 보낸 ACK가 중간에 손상되었다는 의미다.
그러므로 Receiver 측에서는 ACK를 다시 보내주기면 하면 된다.
⑦ 손상되지 않았고, seq num이 0인 rcvpktrk 하위 계층으로부터 도착하였다.
⑧
1) rcvpkt로부터 data를 추출한다.
2) 추출한 data를 상위 계층으로 전달한다.
3) ACK와 checksum으로 이루어진 sndpkt를 만든다.
4) 하위 계층으로 sndpkt을 전달한다.
이후 seqence number를 바꾸어가며 ① ~ ⑧ 과정을 반복한다.
rdt 2.2 (NAK 없는 rdt)
rdt 2.2에서는 2.1과 다르게 Receiver가 NAK 대신 가장 최근에 정상수신한 패킷에 대한 ACK를 보낸다.
NAK 대신 ACK가 전달된다는 것을 제외하고 rdt 2.1과 큰 차이는 없다.
Sender 측에서는 수신된 ACK의 sequence number를 확인하고,
해당 seq num 이전의 패킷들은 모두 정상 수신, 이후의 패킷들은 모두 전송 실패로 간주한다.
Sender의 동작을 FSM으로 표현하면 다음과 같다.
초기 상태는 seq num이 0인 패킷을 만들기 위해 상위 계층으로부터 데이터를 기다리는 상태다.
① 상위 계층의 프로세스로부터 데이터가 도착한다.
② 전송 계층에서 전달받은 데이터에 sequence number 0과 checksum을 추가해 sndpkt을 만든다.
③ 전송 계층에서 생성한 패킷을 하위 계층으로 전달한 다음 0번 패킷에 대한 ACK(이하 ACK0)를 받기 위해 대기하는 상태로 변환한다. 이 떄 Receiver로부터 ACK를 받을 때까지 sndpkt를 보관한다.
④ Receiver로부터 전달받은 rcvpkt이 손상되었거나 ACK1일 경우
⑤ sndpkt을 재전송한다.
⑥ 또는 Receiver로부터 전달받은 rcvpkt이 손상되지 않았고, ACK0일 경우
상위 계층으로부터 데이터를 받아 seq num이 1인 패킷을 만들기 위해 대기하는 상태(wait for call 1 from above)로 변환한다.
이후 seqence number를 바꾸어가며 ① ~ ⑥ 과정을 반복한다.
Receiver의 동작 과정은 다음과 같다.
초기 상태는 하위 계층으로부터 seq num이 0인 패킷을 받기 위해 대기하는 상태다.
① 하위 계층으로부터 손상되었거나 seq num이 1인 패킷(1번 패킷)이 전달된 경우
② 이전에 전달한 sndpkt(ACK1, cksum)을 다시 전달한다.
③ 하위 계층으로부터 손상되지 않은 0번 패킷이 도착한 경우(0번 패킷을 정상 수신한 경우)
④ rcvpkt로부터 data를 추출해 상위 계층으로 전달하고, ACK0와 checksum으로 이루어진 sndpkt를 생성해 전달한다.
이후 seqence number를 바꾸어가며 ①② 혹은 ③④ 과정을 반복한다.
rdt 3.0
rdt 3.0은 하위 채널에 비트 오류와 패킷 손실이 모두 발생하는 환경을 고려한다.
즉 패킷이 손상될 수도 있고, 패킷이 아예 전달되지 못할 수도 있다.
Sender 측에서는 데이터에 checksum, seq num을 추가해 패킷을 만들어 전송하고,
합리적인 시간동안 대기한 뒤 그 안에 ACK가 도착하지 않으면 패킷을 재전송한다.
Receiver 측에서는 패킷을 정상 수신하면 해당 패킷에 대한 ACK를 전송하고, 패킷이 손상되었다면 가장 최근에 정상 수신한 패킷에 대한 ACK를 전송한다. rdt 2.2에서와 완전히 똑같이 동작한다.
Sender의 동작 과정은 다음과 같다.
초기 상태는 seq num이 0인 패킷을 생성하기 위해 상위 계층으로부터 데이터를 기다리는 상태다.
①
- 상위 계층으로부터 데이터가 도착한다.
- 데이터에 sequence number와 checkshum을 추가해 패킷(sndpkt)을 만든다.
- 생성한 sndpkt를 하위 채널로 전송한다.
- 타이머를 시작한다.
- ACK0를 받기 위해 대기하는 상태로 변환한다.
②
하위 채널로부터 전달된 응답이 손상되었거나 ACK1인 경우 무시한다.
③
- 대기 시간이 경과하여 timeout이 발생한다.
- 하위 채널로 패킷을 재전송한다.
- timer를 다시 시작한다.
④
하위 채널로부터 손상되지 않은 ACK0 응답이 도착한 경우, 타이머를 멈추고 1번 패킷(seq num이 1인 패킷)을 생성하기 위해 상위 계층으로부터 데이터를 기다리는 상태로 변환한다.
⑤
이 상태에서 네트워크 지연 등으로 Receiver로부터 응답이 도착할 수 있다. 하지만 무시한다.
이전의 rdt 2.x에서는 응답을 확인하여 재전송 여부를 결정했지만,
rdt 3.0에서는 time out이 발생했을 때만 재전송하고, 그 외에 도착하는 응답은 무시한다.
time out은 어찌 되었건 앞서 전송한 패킷에 대한 ACK가 시간 내에 도착하지 않으면 발생하므로,
앞서 고려한 에러 상황을 다시 고려할 필요가 없어지기 때문이다.
rdt 3.0에서의 패킷 전송 과정을 시나리오 기법으로 표현하면 다음과 같다.
1. a1이 손상된 경우
- p0, a0는 정상적으로 교환되었다고 가정한다.
- p1 패킷이 제대로 전달되었고, a1이 전달 중 손상되었다.
- Sender측에서 a1을 정상수신하지 못했으므로 다음 패킷(p0)를 전송하지 못한 채 time out이 발생한다.
- time out이 발생하여 Sender가 p1을 재전송한다.
- Receiver는 도착한 p1에 대해 a1을 전송한다. p1 패킷은 이전에 받은 적 있으므로 버린다.
- 결과적으로 Sender, Receiver가 p1, a1을 정상수신했으므로 통신에 문제가 발생하지 않는다.
- 같은 방식으로 패킷 교환이 계속 진행된다.
2. a1이 손실된 경우
- p0, a0는 정상적으로 교환되었다고 가정한다.
- p1 패킷이 제대로 전달되었고, a1이 전달 중 손실되었다.
- Sender측에서 a1을 정상수신하지 못했으므로 다음 패킷(p0)를 전송하지 못한 채 time out이 발생한다.
- time out이 발생하여 Sender가 p1을 재전송한다.
- Receiver는 도착한 p1에 대해 a1을 전송한다. p1 패킷은 이전에 받은 적 있으므로 버린다.
- 결과적으로 Sender, Receiver가 p1, a1을 정상수신했으므로 통신에 문제가 발생하지 않는다.
- 같은 방식으로 패킷 교환이 계속 진행된다.
3. a1이 지연된 경우
- p0, a0는 정상적으로 교환되었다고 가정한다.
- p1 패킷이 제대로 전달되었고, a1 전송 중 지연이 발생한다.
- Sender측에서 a1을 수신하기 전에 time out이 발생한다.
- time out이 발생하여 Sender가 p1을 재전송한다.
- Receiver는 도착한 p1에 대해 a1을 전송한다. p1 패킷은 이전에 받은 적 있으므로 버린다.
- Sender가 p1을 재전송한 이후에 지연 전송된 a1이 도착한다.
- Sender는 a1을 수신했으므로 다음 패킷인 p0를 전송한다.
- Sender가 p0을 전송한 이후 Receiver가 두번째로 보낸 a1이 도착한다.
- Sender는 이미 p0을 전송한 후 a0을 기다리는 상태이므로 a1은 무시한다.
- 결과적으로 Sender, Receiver가 p1, a1을 정상수신했으므로 통신에 문제가 발생하지 않는다.
- 같은 방식으로 패킷 교환이 계속 진행된다.
rdt 버전별 차이점을 표로 정리하면 다음과 같다.
rdt 1.0 | rdt 2.0 | rdt 2.1 | rdt 2.2 | rdt 3.0 | |
하위 채널 조건 | 완전히 신뢰적 (비트오류 x, 패킷 손실 x) |
비트 오류 존재 | 비트 오류 존재 | 비트 오류 존재 | 비트 오류 존재 패킷 손실 존재 |
패킷 구성 | data | data, checksum |
data, checksum, sequence num |
data, checksum, sequence num |
data, checksum, sequence num |
대응 가능한 문제점 |
패킷이 손상된 경우 | 패킷, 응답이 손상된 경우 | 패킷, 응답이 손상된 경우 | 패킷, 응답이 손상된 경우, 패킷이 손실된 경우 |
|
응답 | ACK, NAK | ACK, NAK | ACKn | ACKn |
'Network > old' 카테고리의 다른 글
Stop-and-Wait, Go-Back-N, Selective Repeat (0) | 2023.04.16 |
---|---|
rdt 요약 시나리오 (0) | 2023.04.14 |
TCP의 기능 (0) | 2023.03.21 |
ARP (Address Resolution Protocol) (0) | 2023.01.18 |
서킷 스위칭과 패킷 스위칭 (0) | 2023.01.05 |