본문 바로가기

CS/컴퓨터 네트워크

15. reliable data transfer 원리 : RDT(1.0, 2.0, 2.1, 2.2, 3.0)

 

tcp의 안정적 데이터 전송

application layer에서 sender에서 데이터를 보내고 transport layer에서 tcp를 제공하고 receiver에 도착함

보내는 과정의 함수가 있을 텐데 여기는 unreliable함

이 unreliable한 곳을 뚫고 가면 receiver의 transport layer에서 reliable하게 함

 

* RDT : reliable data transfer protocol

방향성이 한쪽으로 가는 거라서 unidirectional

보통 FSM을 사용하게 됨 FSM은 finite state machines인데 유한상태머신임

머신이 하나의 상태에서 다음 상태로 넘어갈 때 이벤트가 있고, 액션이 있음

어떤 이벤트가 state1에서 발생하고 state2로 넘어갈 때, 그 때 액선을 트리거하는 조건과 액션이 들어가는 구조로 설계

 

*RDT 1.0 : over a reliable channel

채널이 perfect하다고 생각하는 거 : 채널이 안정적이라서 플립에러 패킷손실 등 에러가 하나도 없다고 생각

초기 상태에서 시작함 - 상태가 하나밖에 없음

application layer에서 transport layer로 전송할 데이터들이 내려오면 패킷을 만들고 udt_send로 패킷을 전송

udt_send 이벤트가 일어나면 밑에 있는 액션을 함 

이렇게 쳇바퀴를 도는 방식

데이터 손실 등 문제가 없으면 이렇게 설계 가능

 

*RDT 2.0 : channel with bit error

더 진화된 버전 : 비트에러, 플립이 일어날 수 있다고 생각하고 이때 에러 처리에 대해 생각하고 설계

ack : 잘 받았다고, nak : 못 받았다고 하는 신호를 보냄

데이터를 보내는 메세지는 아닌데 그냥 정보에 관련된 내용을 하나 더 보내는 거임

sender

application layer로부터 무언가가 오기를 기다렸다가 rdt_send 이벤트가 발생하면

두번째 state로 바꿔서 ack이나 nak을 기다림

receiver

rdt_rcv 이벤트가 일어났을 때 nak이 있으면 이전에 보낸 데이터를 다시 전송하고 ack이 있으면 다시 기다리는 상태로 전환

반면에 receiver는 network layer에서 패킷을 받았는데 그 패킷에 에러가 있으면 nak을 전송하고 상태는 그대로 있음

무언가 받았는데 checksum으로 에러가 없는 것을 확인하면 패킷을 꺼내고 application layer에 전달하고 ack를 전송하는 액션

 

에러핸들링이 되는데 데이터 패킷에 ack이나 nak을 보냈는데 corrupted가 발생할 수 있음

똑같은 데이터를 계속 보내는 게 좋은 방법이지는 않음

그래서 sender가 패킷에 시퀀스, 즉 순서를 넣어서 보냄

만약 receiver에서 1번을 받았는데 1번이 또 오면 굳이 받을 필요가 없어서 duplicate pkt을 버림

 

*rdt 2.1 : handles garbled ack/naks

garbled ack/naks가 오면 초기 상태로 가고 0번 패킷이 내려오기를 기다림

sender

rdt_send 이벤트가 일어나면 패킷을 만들고 시퀀스 0을 넣어서 전송하고 state를 전환하여 ack/nak을 기다림

recevier에서 받고 corrupted거나 nak이 왔으면 이전에 보낸 데이터를 다시 보낼텐데

만약 받았는데 ack,nak이 corrupted도 아니고 ack이면 다음 순서인 1번 패킷을 기다리는 state가 됨

sender는 1번을 넣어서 보내고 nak이면 다시보내고 ack이면 다시 0번 상태가 됨

receiver

receiver도 초기상태가 먼저 되고 패킷을 받음

corrupted도 아니고 시퀀스도 내가 기다리는 시퀀스와 일치하면 ack을 보내고 다음 시퀀스를 기다리는 상태로 전환

받은 패킷 내의 시퀀스와 내가 기다리는 시퀀스가 다르면 ack은 보내고 상태는 안바꿈

 

rdt2.1에서는 시퀀스 넘버를 추가하게 되는데 이게 0,1로 충분하지 않음

tcp는 시퀀스 넘버가 충분히 많음

ack하고 nak을 받는 부분을 계속 확인하는 부분도 있어야하고

방금 0을 받았는지 1을 받았는지도 계속 확인해야함

receiver부분에서도 패킷이 동일한 패킷인지 아닌지 체크해야하고 ack/nak을 잘 보냈는지 확인할 수 없는 단점이 있음

 

*rdt2.2 : NAK-free protocol

nak 대신에 ack1, ack0으로 바꿔서 설계

sender

초기 상태는 0을 기다리는 상태

데이터를 보내는 이벤트가 일어나고 시퀀스 0을 넣어서 패킷 전송

그 다음 0 이 있는 ack가 오기를 기다림

만약 1이 있는 ack를 받으면 nak이라고 간주

receiver

도착한 패킷이 시퀀스도 일치하고 에러가 없다면 application layer에 올리고 network layer에서 ack1을 보냄

시퀀스가 0인 패킷을 받아야 하는데 1인 패킷을 받으면 ack1을 보냄

 

*rdt 3.0 : channels with errors and loss

채널에서 에러랑 패킷 손실을 핸들링함

새로운 부분 : 우리가 보낸 data나 ack이 중간에 손실될 수 있다고 생각

재전송을 위해서 checksum과 sequence number가  필요함

-방법 : sender가 데이터를 전송하고 합리적인 시간만큼 기다린 뒤 ack가 없으면 다시 보냄

ack를 받으면 필요한 패킷을 또 보낸거라서 duplicate pkt이 됨

타이머 추가

sender

초기 상태에서 데이터를 보낼 때 시퀀스 넘버 0을 넣어서 보내고

network layer에서 send를 하고 타이머를 킴

그 상태에서 ack0을 기다리는 상태로 전환

receiver에서 잘 받았다고 왔는데 corrupted 됐거나 ack0대신 ack1이 오면 가만히 있음

그러다 타임 아웃이 되면 다시 보내고 다시 타이머를 킴

다시 받았는데 원하는 ack0이 오면 타이머 스탑하고 다음 상태로 넘어감

 

 

 

 

'CS > 컴퓨터 네트워크' 카테고리의 다른 글

14. Connectionless transport : UDP  (0) 2020.04.14
12. 트랜스포트 레이어  (0) 2020.04.14
11. P2P  (0) 2020.04.07
10. DNS  (0) 2020.04.07
9. SMTP, POP3, IMAP  (0) 2020.04.07