Computer Networking- 03. Transport Layer(Reliable data transfer)

CHO WanGi·2023년 12월 6일
0

Network

목록 보기
2/11

Principle of Reliable data transfer

신뢰성 있는 데이터 송/수신을 위해서라면, 신뢰성 있는 Protocol을 Transport 계층에서 사용하고, network 계층에선 비 신뢰적인 채널을 활용하는 것으로 서비스 구현

Getting Started

점진적으로 송/수신측의 Rdt 프로토콜이 발전해옴
오직 단방향 데이터 통신만 생각함
FSM을 사용하여 송/수신측을 특정

rdt 1.0

신뢰적 채널을 통한 신뢰할 수 있는 데이터 통신

  • 비트 에러도 없고, 패킷 손실도 없는 상태
  • 송신자는 데이터를 채널로 보내고, 수신자는 이것을 읽기만 하면 됨.

rdt 2.0

패킷의 비트가 뒤집힐 수 있는 경우(비트에러 발생 가능) -> 어떻게 이를 회복할까?

  • 체크섬을 활용하여 비트 뒤집힘 감지
  • ACKs(인지) 와 NAKs(인지X) 활용
    ACks의 경우 수신자가 송신자에게 패킷 잘 받았다고 하는 것이고, NAKs 의 경우, 무언가 에러가 발생했다는 의미이기때문에, 송신자가 재 전송을 하게끔 하는 것

만약 에러가 발생하여 NAKs가 발생하면, 위 사진의 flow로 진행
송신자가 NAKs를 받는 순간 재전송, ACK를 받으면 멈춤.

=>그런데 만약, ACK/NAK이 손상이 되면?

송신자는 잘 받았는지 확인할 수 있는 수단이 없다, 그렇다고 재송신만 주구장창 할 수 없는게 동일 데이터를 다시 받는 경우가 될 수도 있기 때문

=> Sequence Number와 Stop and wait를 활용해보자

rdt 2.1(시퀀스 넘버 활용)

sndpkt에 0번부터 순서대로 send할때마다 시퀀스 넘버를 붙여서 송신.

  • 송신측
  1. 데이터 받으면 헤더에 0 붙여서 패킷을 만들고 보내고 상태를 변경
  2. 받은 결과가 NAK이면 재전송하고 상태유지(-> ACK이나 NAK 0 기다림)
  3. 받은 결과가 ACK이면 상태 변경
  4. 데이터 받으면 헤더에 1 붙여서 패킷 만들고, 보내어 상태를 변경
    위 4단계를 반복
  • 수신측
  1. 0번 대기 상태, 받은 결과가 문제가 없고 0번임이 확인, 데이터 가공하여 어플리케이션 계층으로 보내고, ACK를 송신측으로 보내주고 상태를 변경
  2. 받은결과에 문제가 있으면 NAK을 보냄
    2-1. 만약 받은 결과가 문제가 없긴 한데 0번이 아니고 1번이라면 ACK은 만들어서 보냄
  3. 둘다 어플리케이션 계층으로 보내는 것 없으며 상태 유지
  4. 1번 대기 상태, 위 내용 반복

논의점

  • 송신측
    패킷에 시퀀스 넘버를 붙이는데, stop and wait을 활용하면 0과 1로만으로도 통신 가능
    받은 ACK/NAK이 문제가 없는지 확인
    ACK을 받아야 다음 패킷을 송신 -> 상태가 2배 많음(전에 온 숫자, 어떤 숫자가 올지 대기)

  • 수신측
    받은 패킷이 중복된 것인가 확인

rdt 2.2 : A NAK-free protocol

2.1 과 동일하지만, NAK 없이 ACK만 사용하여 확인
수신측은 제대로 문제없이 받은 마지막 패킷에 대한 ACK에 시퀀스 넘버 넣어서 보내줌
송신측은 중복된 넘버의 ACK가 NAK의 기능을 수행 -> 중복된다면 현재 패킷 재전송

  • 송신측
  1. ACK 0 대기, 문제있거나 ACK 1을 받았다면 재전송 후 상태 유지
  2. 문제 없고 ACK 0 을 받으면 다음상태로 변경
  • 수신측
  1. 1번 패킷 수신, 상태 변경하면서 sndpkt(ACK 1) 만들고 상태 변경
  2. 0 기다리는 상태, 문제 발생하거나 ACK 1을 받으면 sndpkt(ACK 1) 보내고 상태 유지
    송신자 입장에서 ACK 0 대기 상테인데 ACK 1 들어오기 때문에 재전송 해주어야 함.

rdt 3.0 : channels with errors and loss

  • 비트 에러와 패킷 로스도 발생할 수 있는 경우(오버플로우로 인한 버퍼 용량 초과 같은 경우)
    송신은 멀쩡히 잘 갔는데, 수신측에서 못받은 경우

접근법

수신측은 아무것도 받지 못함 -> 패킷이 오지 않음 -> 동작 X
송신측은 패킷 보내고 "적절한 시간" 동안 ACK 대기

  • ACK 오지 않으면?
    재전송
    어떤 이유로 손실이 아니라 느리게 갔다면 데이터 중복 발생 가능(시퀀스 넘버로 해결 가능) -> 타이머 구현 필요

timer 구현

  1. 패킷 만들고 전송 후 타이머 시작, 상태 변경
  2. 오긴 왔는데 다른 시퀀스 넘버 혹은 문제 발생시 타이머 및 상태 변경없이 그대로 유지
  3. 타임아웃 걸리면 재전송 후 타이머 다시 시작, 상태 유지
  4. ACK 오면 타이머 스탑하고 상태변경
  • Premature Timeout / delayed ACK
    타이머의 시간이 너무 짧으면, 불필요한 재전송 횟수가 증가 -> 퍼포먼스 저하
    타이머의 시간이 너무 길면, 손실 발생시 복구까지 너무 오래 걸림 -> 적절한 타이머 구현이 중요

Perfomance at rdt 3.0(Stop-and-wait)

동작은 기깔난데 성능이 구데기

  • Example: 1Gpbs(10^^9) link, 15ms drop, delay 8000bit packet
    전송지연(패킷 내보내는데 걸리는 시간) = 8 microsec
    전파지연(한 패킷이 끝까지 가는데 걸리는 시간) = 15ms
    결국 송신 총 시간은 전송지연과 전파지연의 합 = 15.008ms

RTT + 전송지연 + 전파지연 = 15 + 15.008ms = 30.008ms
8000 비트 보내는데 30.008, 0.00027 (1에 가까울 수록 효율성 높음)

=> 왜? 하나 보내고 돌려받을 때 동안 대기하는 시간이 아깝다

Pipelined protocols

보내고 기다리지말고, 여러개를 보내고 여러개의 ACK를 받아보자

다만, 구별을 위한 시퀀스 넘버 여러개가 필요하고, 버퍼링도 필요
-> go-Bakc-N, selective Repeat이 주로 사용

Go-back-N

  • 송신측

window Size : N개까지 한번에 보낼 수 있음
Send_Base : 윈도우 사이즈 내 가장 앞의 패킷
nextseqnum: 다음으로 보내질 패킷의 시퀀스넘버
슬라이딩 도어 처럼 한칸씩 윈도우 사이즈가 이동하는 개념(사이즈 유지)

Cumulative ACK : ACK(n), n번 시퀀스넘버까지 ACK를 받았다.
-> ACK(1) 받고 ACK(3)을 받아도 2번에 대해선 잘 받았다고 간주
timeout(n) : 6,7,8번을 이미 보냈더라도 4라는 시퀀스 넘버서 타임아웃 걸리면, 4부터 전부 다시 보냄(4,5,6,7,8)
이래서 Go-back-N.
제대로 못받은게 있다면 N으로 돌아가서 다시 재전송


pkt2가 loss, 수신측이 timeout 올때까지 ack2를 보내지 않았기때문에, 다시 2번으로 돌아가서 2,3,4,5를 재전송

Selective Repeat : the approach

Pipelining -> 여러개의 패킷을 한번에 보내는 것,
따라서 수신측은 받은 각각의 패킷들에 대해 ACK을 보내는 방식
-> 1~4 전송, 수신측에서 1,3만 받으면 ACK 1, ACK3만 보내줌
-> 송신측, 각각의 타임아웃 기다리다가 안오면 각각 패킷을 재전송
따로 받을 패킷을 보관할 버퍼가 필요(문제 있어도 일단 저장해놓고, 나중에 부족하면 채워지는 구조이기 때문)
사용하는 시퀀스 넘버는 송신측의 Window Size와, 수신측의 Window SIze 크기의 합보다 무조건 크거가 같다

pkt 2가 loss, 송신측이 받은 ACK은 1,3,4,5
Pkt 2만 재전송
이래서 선택적 반복, 못받은 것만 선택해서 다시 보내는 방식

profile
제 Velog에 오신 모든 분들이 작더라도 인사이트를 얻어가셨으면 좋겠습니다 :)

0개의 댓글