2020. 6. 9.

[Network] 3.4 신뢰적 data 전송의 원리 1


*신뢰적인 data 전송의 원리

T/L 뿐아니라 A/L, L/L에서도 매우 중요한 문제이다.
매우 중요한 topics

~ 0 charne 
ra 「 
冖 b) $ ~ 一 0 ! 9m940 一 一 8 
0b 一 c 
reoc 」 一 0

하위계층이 비 신뢰적인 채널인 경우 상위채널에서 신뢰적인 통신을 제공 해야 한다.

# 상태, 액션, 이벤트로 설명한다.
# transport layer TCP 어떻게 신뢰적인 데이터를 제공하느냐에 대한 설명

*신뢰적 Data transfer

r & _ send 
send oata 
ansr« protocol 
side 
send soel 
deliver ( 
Ozta 
ttÜ1sfer pqotccol 
receivt' sde 
receive 
side

rdt_send() : 하위 rdt Data 전달하기 위해 app가 호출
  • 어플리케이션이 TCP에게 메시지를 전달한다.
udt_send() : 비신뢰적인 하위 채널에 Data 전달하기 위해 rdt 호출
  • TCP IP에게 데이터를 주는것
deliver_data() : rdt가 상위 layer Data를 전달하기 위해 호출
  • IP TCP에게 데이터를 주는것
rdt_rcv() : 상위 rdt Data를 전달하기 위해 호출
  • 세그먼트를 소켓을 통해 어플리케이션에게 전달해준다.

# event : 남이 나에게 해주는 (누구를 기준으로 하느냐를 알려줘야한다.)
# action : 내가 하는것

sender
# 어플리케이션이 데이터를 주길 기다린다.
# TCP 메시지를 받아서 세그먼트를 만들어 IP에게 보낸다.
recevier
# IP 수신자에게 세그먼트를 받는다.
# 데이터를 어플리케이션에게 준다.

# unreliable channel 이라는 채널이 불안정하기 떄문에 TCP 이렇게 복잡한 작업을 한다.

앞으로의 전개
  • 점점 복잡해지는 하위채널을 고려 신뢰적 data 전송 protocol의 송신자 측면과 수신자 측면을 전개
  • 단 방향 전송만을 고려 : 이 경우에도 제어 패킷은 양방향 전송이 필요
  • FSM으로 표현

state: when in this 
"state" next state 
uniquely determined 
by next event 
state 
1 
event causinq state transition 
actions taken on state transition 
event 
ctions 
state 
2

참고 : datagram이라는 용어보다는 일반적인 packet이라는 용어를 사용한다.

# 프로토콜 : 이벤트가 발생하면 액션을 취하는
# 스테이트먼트 : 상태를 전이하는


*rdt 1.0 : 신뢰적인 채널에서 rdt

하위 채널이 완전히 신뢰적인 경우
  • no bit error
  • no loss of packets
FSM
  • 송신측은 상위 layer data를 받아 하위 채널로 packet을 전달한다.
  • 수신측은 하위 채널에서 packet을 수신하고 data를 상위 layer로 전달한다.

ait for 
call from 
above 
rdt_send(data) 
packet = make_pkt(data) 
udt_send(packet) 
sender 
Wait for 
call from 
below 
rdt_rcv(packet) 
extract (packet,data) 
deliver_data(data) 
receiver

# 동그라미 : 상태
# 직선 : 이벤트
# 직선 아래 : 액션
# 화살표 : 상태정의
# wait for call from adove : 위로부터 뭔가 내려오길 기다리고 있는 상태
# wait for call from below : 아래로부터 뭔가 내려오길 기다리고 있는 상태

# sender
  • rdt_send(data) : app TCP에게 데이터를 주기 위한 ( TCP에선 이벤트)
  • packet=make_pkt(data) : 받은 데이터를 패킷으로 만든다.
  • udt_send(packet) : 만든 데이터를 보낸다.

# receiver
  • wait for call from below : IP로부터 세그먼트가 올라오길 기다리고 있는상태
  • rdt_rcv(packet) : IP로부터 패킷을 받는다.
  • extract(packet,data) : 패킷으로부터 데이터를 추출
  • deliver_data(data) : app 에게 데이터 전달

*rdt 2.0 : 비트 오류가 있는 채널

bit error이 가능한 채널에서 rdt : packet의 손실이나 순서는 보장
  • checksum을 통해 bit error감지
# sender 손실의 유무를 보낸뒤에 알수 없다.
수신측의 feedback 필요
  • acknowledgement (ACKs) : receiver sender 에게 pkt를 잘 받았다는 응답
  • negative acknowledgement (NAKs) : receiver sender 에게 pkt error또는 장애가 있다는 응답
  • sender NAK인 경우 pkt 재전송
rdt 2.0에 부가적으로 필요한 protocol (rdt 1.0에 비해서)
  • error 검출
  • receiver feedback : 제어 msg (ACK,NAK)
  • 재전송

  1. sender 패킷 전송
  2. receiver 응답 (ack, nack)
  3. sender 응답을 받고 재송신 판단
  4. sender nack 왓다면 재송신

*rdt 2.0 : FSM

rdt_send(data) 
snkpkt = make_pkt(data, checksum) 
udt_send(sndpkt) 
Wait for 
call from 
above 
Wait for 
ACK or 
NAK 
rdt_rcv(rcvpkt) && 
isNAK(rcvpkt) 
udt_send(sndpkt) 
rdt_rcv(rcvpkt) && isACK(rcvpkt) 
sender 
receiver 
rdt_rcv(rcvpkt) && 
corrupt(rcvpkt) 
udt_send(NAK) 
Wait for 
call from 
below 
rdt_rcv(rcvpkt) && 
notcorrupt(rcvpkt) 
extract(rcvpkt,data) 
deliver_data(data) 
udt_send(ACK)

sender
wait for call from above : app 부터 데이터가 오길 기다리는 상태
rdt_send(data) : app 데이터를 받는다.
sndpkt = make_pak(data, checksum) : 체크섬을 포함한 패킷을 만든다.
udt_send(sndpkt) : ip 패킷을 보낸다
wait for ack or nak : ack, nak 응답이 오길 기다리는 상태 변경
rdt_rvc(rcvpkt) && isNAK(rcvpkt) : NAK 응답을 받는다.
udt_send(sndpkt) : 패킷을 다시 보낸다
wait for ack or nak : ack, nak 응답이 오길 기다리는 상태 변경
rdt_rvc(rcvpkt) && isACK(rcvpkt) : ack 응답을 받는다.
wait for call from above : app 부터 데이터가 오길 기다리는 상태로 변경

receiver
wait for call from below : IP에서 TCP 패킷이 도착하길 기다리는 상태
rdt_rcv(rcvpkt)&&corrupt(rcvpkt) : 패킷을 받았으나 패킷이 깨져서 버림
udt_send(NAK) : IP에게 NAK 보냄
rdt_rcv(rcvpkt)&&notcorrupt(rcvpkt) : 패킷을 받고 패킷이 안깨졌다.
extract(rcvpkt,data) : 패킷을 데이터로 변환
deliver_data(data) : TCP app에게 데이터를 보낸다.
udt_send(ACK) : IP에게 ACK 보낸다.
wait for call from below : IP에서 TCP 패킷이 도착하길 기다리는 상태로 변경

# sender 데이터가 꺠지는 것을 가정한것

*rdt 2.0 : rcvpkt OK

rdt_send(data) 
snkpkt = make_pkt(data, checksum) 
udt send snd k 
ait for 
call from 
above 
ait fo 
ACK or 
N AK 
rdt_rcv(rcvpkt) && 
isNAK(rcvpkt) 
dt_send(sndpkt) 
rdt_rcv(rcvpkt) && isACK(rcvpkt) 
rdt_rcv(rcvpkt) && 
corrupt(rcvpkt) 
udt_send(NAK) 
Wait for 
call from 
below 
rdt rcv rcv && 
notcorrupt(rcvpkt) 
extract(rcvpkt,data) 
deliver_data(data) 
udt_send(ACK)

*rdt 2.0 : rcvpkt error

rdt_send(data) 
snkpkt = make 
udt send s 
Wait for 
call from 
above 
_pkt(data, checksum) 
t rcv rcv kt && 
udt_send(sndpkt) 
ait for 
ACK or 
NAK 
rdt_rcv(rcvpkt) && isACK(rcvpkt) 
rdt rcv rcv kt && 
corrupt(rcvp ) 
send NAK 
Wait for 
call from 
below 
rdt rcv rcv && 
notcorrupt(rcvpkt) 
extract(rcvpkt,data) 
deliver_data(data) 
udt_send(ACK)


1. (sender - TCP 상태) wait for call from above
- app로 부터 데이터가 오길 기다리는 상태
2. (sender - TCP 이벤트) rdt_send(data)
- app로부터 TCP가 데이터를 받는다.
3. (sender - TCP 액션) sndpkt = make_pkt(data, checksum)
- 체크섬을 포함한 패킷을 만든다.
4. (sender - TCP 액션) udt_send(sndpkt)
- TCP는 IP로 세그먼트를 보낸다
5. (sender - TCP 상태) wait for ack or nak
- TCP는 IP로부터 ack, nak의 응답이 오길 기다리는 상태를 변경한다.
6. (receiver - TCP 상태) wait for call from below
- IP에서 TCP가 세그먼트가 도착하길 기다리는 상태
7. (receiver - TCP 이벤트) rdt_rcv(rcvpkt)&&corrupt(rcvpkt)
- IP로부터 패킷을 받았으나 패킷이 깨져서 버림
8. (receiver - TCP 액션) udt_send(NAK)
- TCP는 IP에게 NAK 세그먼트를 보냄
9. (sender - TCP 이벤트) rdt_rvc(rcvpkt) && isNAK(rcvpkt)
- IP로부터 TCP는 NAK 응답을 받음
10. (sender - TCP 액션) udt_send(sndpkt)
- TCP는 IP로 세그먼트를 다시 보낸다.
11. (receiver - TCP 이벤트) rdt_rcv(rcvpkt)&&notcorrupt(rcvpkt)
- IP로부터 TCP는 세그먼트를 받고 패킷이 깨지지 않은것을 확인
12. (receiver - TCP 액션) udt_send(NAK)
- TCP는 IP에게 NAK를 보냄
13. (receiver - TCP 액션) extract(rcvpkt,data)
- TCP는 세그먼트를 데이터로 추출
14. (receiver - TCP 액션) deliver_data(data)
- TCP가 APP에게 데이터를 보낸다.
15. (receiver - TCP 액션) udt_send(ACK)
- TCP가 IP에게 ACK를 보낸다.
16. (receiver - TCP 상태) wait for call from below
- IP에서 TCP가 패킷이 도착하길 기다리는 상태로 변경
17. (sender - TCP 이벤트) rdt_rvc(rcvpkt) && isACK(rcvpkt)
- IP로부터 TCP는 ACK 응답을 받는다.
18. (sender - TCP 상태) wait for call from below
- IP에서 TCP가 패킷이 도착하길 기다리는 상태로 변경
 
*rdt 2.0 : 치명적인 결함

ACK/NAK가 훼손되는 경우
  • sender receiver쪽에 어떤일이 벌어졌는지 알 수 없다.
  • 재전송으로 packet이 중복될 수 있다.

중복을 제어하는 방법
  • sender pkt sequence number를 추가한다.
  • ACK NAK가 변형되면 sender pkt를 재전송한다.
  • receiver는 중복된 pkt을 버린다.
  • rdt 2.1
  • 그래서 시퀀스넘버에 0, 1밖에 없다.

stop and wait
Sender pkt 하나를 전송한후 receiver 로 부터 response가 올때까지 대기한다.
-> response가 없으면 계속 기다린다

# ACK/NAK 훼손되면서 시퀀스 넘버가 나오는 계기가
# 여기서의 시퀀스 넘버는 패킷이 중복되는지 아닌지 확인하기 위한

*rdt 2.1 : sender

rdt_send(data) 
sndpkt = data, checksum) 
udt_send(sndpkt) 
Wait for 
call O fro 
above 
rdt_rcv(rcvpkt) 
&& notcorrupt(rcvpkt) 
Wait for 
ACK or 
NAK O 
rdt_rcv(rcvpkt) && 
( corrupt(rcvpkt) Il 
isNAK(rcvpkt) ) 
udt_send(sndpkt) 
rdt_rcv(rcvpkt) 
&& notcorrupt(rcvpkt) 
&& isACK(rcvpkt) 
&& isACK(rcvpkt) 
rdt_rcv(rcvpkt) && 
( corrupt(rcvpkt) Il 
isNAK(rcvpkt) ) 
udt_send(sndpkt) 
Wait for 
ACK or 
NAK 1 
Wait for 
call 1 from 
bove 
rdt_send(data) 
sndpkt = make_pkt(l , data, checksum) 
udt_send(sndpkt)

# 대각선으로 나누면 둘이 똑같다.
# 원래는 시퀀스넘버를 미리 주고 받는다.
상태) wait for call 0 from above
  • TCP 0 패킷을 보내기 위해서 APP에서 보내는 데이터를 대기 중인 상태
이벤트) rdt_send(data)
  • APP로부터 TCP 데이터를 전달
액션) sndpkt = make_pkt(0, data, checksum)
  • TCP 시퀀스 넘버 0번과 체크섬과 데이터를 패킷으로 만든다
액션) udt_send(sndpkt)
  • TCP 세그먼트를 IP 전달한다.
상태) wait for ACK or NAK 0
  • TCP 0 패킷에 대한 ACK 혹은 NAK 기다리는 상태로 변경 (ACK, NAK에는 시퀀스 넘버가 0번이 포함되지 않음)
이벤트) rdt_rcv(rcvpkt)&&(corrupt(rcvpkt) || isNAK(rcvpkt) )
  • TCP IP 부터 패킷을 받았는데 패킷이 깨졌거나 NAK)
액션) udt_send(sndpkt)
  • TCP IP 패킷을 다시 보낸다.
이벤트) rdt_rcv(rcvpkt)&&notcorrupt(rcvpkt)&&isACK(rcvpkt)
  • TCP IP로부터 패킷을 받아서 깨지지 않은것과 ACK인지 확인한다.
상태) wait for call 1 from above
  • TCP 1 패킷을 보내기 위해서 APP에서 보내는 데이터를 대기 중인 상태로 변경된다.


댓글 없음:

댓글 쓰기