rdt 2.0 

: 비트 오류가 있는 채널 (패킷이 가다가 망가지는 경우)

- TCP 하위에 있는 채널이 신뢰적X 전송하는 패킷만 망가진 경우

- 데이터가 손상되었는지 확인하는 알고리즘 필요 (= checksum을 같이 전송)

- 재전송을 하기 위해서는 메모리에 데이터를 저장하고 있어야 한다.

- 버퍼에 ACK까지 보낸 패킷을 가지고 있어야 함  (*잘 받았다는 응답 : ACK / NAK : 잘 못받음)

 

Sender 

• state

 - Wait for call from above : 프로세스가 TCP를 호출하기를 기다린다. 

• event

 - rdt_send(data) : Process > TCP [data] 전달 

• action

 - sndpkt = make_pkt(data, checksum) : data를 이용해 checksum 생성 후 data와 checksum으로 패킷 생성 

 - udt_send(packet) : TCP > IP [packet] 전달

→ state 변화

 - Wait for ACK or NAK : 패킷 전송후 ACK or NAK가 오기를 기다린다.

  (재전송을 하기 위해 메모리에 데이터 저장)

 

i) 응답 패킷이 NAK인 경우

• state

 - Wait for ACK or NAK : 패킷 전송후 ACK or NAK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && isNAK(rcvpkt) : IP > TCP [응답패킷] 전달 & NAK 응답으로 

• action

 - udt_send(packet) : TCP > IP [packet] 전달

→ state 변화

 - Wait for ACK or NAK : 패킷 전송후 ACK or NAK가 오기를 기다린다.

 

ii) 응답 패킷이 ACK

• state

 - Wait for ACK or NAK : 패킷 전송후 ACK or NAK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && isNAK(rcvpkt) : IP > TCP [응답패킷] 전달 & NAK 응답

• action

 - udt_send(packet) : TCP > IP [packet] 전달 (메모리에 저장된 패킷)

→ state 변화

 - Wait for call from above : 프로세스가 TCP를 호출하기를 기다린다. 

 

Receiver

i) 응답 패킷이 NAK인 경우

• state

 - Wait for call from below : TCP를 IP가 호출하기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && corrupt(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 망가진 경우

• action

 -  udt_send(NAK) : TCP > IP [NAK] 전달

→ state 변화

 - Wait for call from below : TCP를 IP가 호출하기를 기다린다.

 

ii) 응답 패킷이 ACK

• state

 - Wait for call from below : TCP를 IP가 호출하기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 정상인 경우

• action

 - extract (packet, data) : 수신 패킷에서 data 추출

 - deliver_data(data) : TCP > Process [data] 전달

 -  udt_send(ACK) : TCP > IP [ACK] 전달

→ state 변화

 - Wait for call from below : TCP를 IP가 호출하기를 기다린다.

 

◾ rdt 2.0 결함

• ACK, NAK가 손상되는 경우

 - TCP에서는 ACK, NAK 손상된 경우 모두 NAK라고 생각 > 패킷이 중복해서 재전송될 가능성이 높아짐.

• 중복 제어 필요 : rdt 2.1

 - sender는 pkt에 sequence number를 추가한다.
 - ACK나 NAK가 변형되면 sender는 pkt를 재전송한다.
 - receiver는 중복된 pkt을 버린다.


rdt 2.1

: 전송하는 패킷, 응답 패킷 둘다 망가진 경우

 

• Sender
 - pkt에 seq #를 추가한다.
 - 두개의 seq #만으로 충분하다. (이전 송신된 pkt와의 중복만 검사)
 - ACK/NAK의 손상을 검사한다.
 - 상태가 rdt 2.0보다 두배 많다.
  (현재 전송 pkt의 seq #가 0인지 1인지 기억하고 있어야 한다.)

 

• Receiver
 - 수신된 pkt의 중복여부를 검사해야한다. (pkt의 seq #가 0/1인지 검사)
 - receiver는 sender가 ACK/NAK를 정상적으로 수신했는지 알 수 없다.

 

Sender 

Sender

Sender 

• state

 - Wait for call 0 from above : TCP는 0번 패킷을 보내려고 메시지를 기다린다.

• event

 - rdt_send(data) : Process > TCP [data] 전달 

• action

 - sndpkt = make_pkt(0, data, checksum) : data를 이용해 checksum 생성 후 data와 checksum, seq#로 패킷 생성 

 - udt_send(packet) : TCP > IP [packet] 전달

→ state 변화

 - Wait for ACK or NAK 0 : 패킷 전송후 0번 패킷에 대한 ACK or NAK가 오기를 기다린다.

  (재전송을 하기 위해 메모리에 데이터 저장)

 

i) 응답 패킷이 NAK인 경우

• state

 - Wait for ACK or NAK 0 : 패킷 전송후 0번 패킷에 대한 ACK or NAK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && ( corrupt(rcvpkt) || isNAK(rcvpkt)) : IP > TCP [응답패킷] 전달 & (응답패킷이 망가진 경우거나 응답패킷이 NAK인 경우)

• action

 -  udt_send(sndpkt) : TCP > IP [이전에 보낸 패킷] 재전달

→ state 변화

 - Wait for ACK or NAK 0 : 패킷 전송후 0번 패킷에 대한 ACK or NAK가 오기를 기다린다.

 

ii) 응답 패킷이 ACK

• state

 - Wait for ACK or NAK 0 : 패킷 전송후 0번 패킷에 대한 ACK or NAK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 정상인 경우 & 응답패킷이 ACK인 경우

• action

 - X

→ state 변화

 - Wait for call 1 from above : TCP는 1번 패킷을 보내려고 메시지를 기다린다.

 

Receiver

Receiver

Receiver

• state

 - Wait for 0 from below : TCP는 0번 패킷을 받으려고 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq0(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 망가지지X 경우 & seq0 응답 패킷을 수신한 경우

• action

 - extract (packet, data) : 수신 패킷에서 data 추출

 - deliver_data(data) : TCP > Process [data] 전달

 - sndpkt = make_pkt(ACK, chksum) : 패킷에 이상이 없다는 ACK를 checksum과 함께 패킷 생성

 -  udt_send(sndpkt) : TCP > IP [응답패킷] 전달

→ state 변화

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

 

i) 응답 패킷이 NAK인 경우

• state

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

• event

 - rdt_rcv(rcvpkt) && ( corrupt(rcvpkt) || isNAK(rcvpkt)) : IP > TCP [응답패킷] 전달 & (응답패킷이 망가진 경우거나 응답패킷이 NAK인 경우)

• action

 - sndpkt = make_pkt(NAK, chksum) : 패킷에 이상이 있다는 NAK를 checksum과 함께 응답 패킷 생성

 - udt_send(sndpkt) : TCP > IP [응답패킷] 재전달

→ state 변화

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

 

ii) 응답 패킷이 ACK

• state

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq0(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 정상인 경우 & 응답패킷이 0번인 경우

• action

 - sndpkt = make_pkt(ACK, chksum) : 패킷에 이상이 없다는 ACK를 checksum과 함께 응답 패킷 생성

 - udt_send(sndpkt) : TCP > IP [응답패킷] 재전달

→ state 변화

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.


rdt 2.2

: NAK가 없는 rdt

2.1에 시퀀스 넘버가 있다.

시퀀스 넘버를 이용해 개선할 방법을 찾은 게 2.2

 

3way hand shake를 통해 0번과 1번 패킷만 보내겠다고 약속

 

NAK가 없으면 최근에 잘 받은 시퀀스 넘버를 ACK 넣어 보낸다. (ex. 1번 패킷을 보내면 0번패킷까지 잘 받았다는 ACK를 보낸다.)

 

• rdt 2.1과의 차이는 ACKs만을 사용하는 것이다.
• receiver는 NAK 대신 최근에 정확히 수신된 pkt에 대한 ACK를 전달한다.
• Sender는 중복된 ACK를 통해서 중복된 ACK pkt이후에 전송한 pkt이 정상적으로 수신되지 못했음을 안다.

 

• 누적 ACK
: 누적된 ACK를 사용 경우 sender는 마지막 수신한 ACK의 seq # 이전의 pkt는 모두 정상 잔달 되었음을 확인 가능

Sender 

• state

 - Wait for call 0 from above : TCP는 0번 패킷을 보내려고 메시지를 기다린다.

• event

 - rdt_send(data) : Process > TCP [data] 전달 

• action

 - sndpkt = make_pkt(0, data, checksum) : data를 이용해 checksum 생성 후 data와 checksum, seq#로 패킷 생성 

 - udt_send(packet) : TCP > IP [packet] 전달

→ state 변화

 - Wait for ACK 0 : 패킷 전송후 0번 패킷에 대한 ACK가 오기를 기다린다.

 

i) 응답 패킷이 망가진 경우

• state

 - Wait for ACK 0 : 패킷 전송후 0번 패킷에 대한 ACK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && ( corrupt(rcvpkt) || isACK(rcvpkt, 1)) : IP > TCP [응답패킷] 전달 & (응답패킷이 망가진 경우거나 응답패킷 ACK가 1인 경우)

• action

 - udt_send(sndpkt) : TCP > IP [응답패킷] 재전달

→ state 변화

 - Wait for ACK 0 : 패킷 전송후 0번 패킷에 대한 ACK가 오기를 기다린다.

 

ii) 응답 패킷이 ACK

• state

 - Wait for ACK 0 : 패킷 전송후 0번 패킷에 대한 ACK가 오기를 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt, 0) : IP > TCP [응답패킷] 전달 & 응답패킷이 정상인 경우 & 응답패킷이 ACK 0인경우

• action

 - X

→ state 변화

 - Wait for call 1 from above : TCP는 1번 패킷을 보내려고 메시지를 기다린다.

 

Receiver

i) 응답 패킷이 원하는 seq#일 경우

• state

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

• event

 - rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && has_seq0(rcvpkt) : IP > TCP [응답패킷] 전달 & 응답패킷이 망가지지X 경우 & seq0 응답 패킷을 수신한 경우

• action

 - extract (packet, data) : 수신 패킷에서 data 추출

 - deliver_data(data) : TCP > Process [data] 전달

 - sndpkt = make_pkt(ACK, chksum) : 패킷에 이상이 없다는 ACK를 checksum과 함께 패킷 생성

 -  udt_send(sndpkt) : TCP > IP [응답패킷] 전달

→ state 변화

 - Wait for 0 from below : TCP는 1번 패킷을 받으려고 기다린다.

 

ii) 응답 패킷이 원하지 않는 seq#일 경우

• state

 - Wait for 0 from below : TCP는 0번 패킷을 받으려고 기다린다.

• event

 - rdt_rcv(rcvpkt) && ( corrupt(rcvpkt) || has_seq1(rcvpkt)) : IP > TCP [응답패킷] 전달 & (응답패킷이 망가진 경우거나 응답패킷 seq#가 1인 경우)

• action

 - udt_send(sndpkt) : TCP > IP [응답패킷] 재전달

→ state 변화

 - Wait for 1 from below : TCP는 1번 패킷을 받으려고 기다린다.

 

+ Recent posts