본문 바로가기
네트워크/컴퓨터 네트워크 수업

3-4-2. TCP : Connection-oriented transport(2)

by dustnn 2024. 10. 21.
TCP reliable data transfer(rdt)

 

 

rdt service 제공

- pipelined segments

- cumulated acks

- single retransmission timer per connection(socket) : 아직 ack 못 받은 oldest segment(첫 번째 노란색)에 맞춰 timer 설정

 

 

retransmission이 진행되는 경우

1. timeout 발생했을 때

2. 3 duplicate acks(fast retransmission) 발생했을 때: 1번의 허점 보완하기 위해 사용 => 뒤에서 자세히 다룰 예정

 

 

TCP sender측

 

sender의 transport 계층에서 일어나는 event에는 다음 세 가지가 있다.

 

 

SendBase NextSeqNum라는 변수를 정의할 필요가 있다.

- SendBase = 첫 번째 sent but not yet ACKed

* (SendBase-1)까지는 ACK까지 모두 받음

- NextSeqNum = 아직 보내지도 않은 segment 중 첫 번째

* 다음 sequence 내보낼 때 달아서 내보내야 함

 

1. application 계층에서 data 받음

 

- transport 계층은 app 계층에서 받은 sequence#를 포함한 segment 만든다고 했다.

(이때 sequence#는 segment의 첫 번째 data byte)

- timer은 sent but not yet ACKed 가 생기면 작동한다고도 했었다.

 

(단계1) segment 만들고 sequence number을 NextSegNum로 지정한다.

(단계2) network 계층의 IP로 segment 전달

(단계3) NextSegNum 업데이트(이전 NextSeqNum + data length)

(단계4) if(timer currently not running) start timer

 

 

2. timeout 발생

 

- timeout이 발생하면 segment를 retransmit한다.

- retransmit할 때 timer을 다시 켠다.

 

 

(단계1) retransmit not-yet-acked segment (w/ 가장 작은 sequence#)

(단계2) start timer

 

 

3. networt 계층에서 ACK 받음(from sender)

 

- sent but not ACKed 리스트를 업데이트(ACKed로 바꾸기)

- 업데이트된 것에 따라 timer 다시 켠다. (새로운 첫 번째 "sent but not ACKed")

 

ACK 받았고, ACK field('A'라는 flag값) value=y

=> "y-1까지의 값은 다 잘 받았고, y번째 sequence# 달고온 값 기다리겠다"

 

if(y > SendBase) {
 SendBase = y  #y-1번째 ACK까진 잘 받았고 y번째 ACK 받을 차례
      if(there are currently not-yet-acked segments)
          start timer
      else stop timer  #set but not yet(노란색)이 이제 더이상 없음 => 이제 ACK 다 받았다!!
}

 

 

TCP receiver측

 

TCP receiver측에서 일어나는 event들은 다음과 같다.

 

1. expected sequence#에 해당하는 in-order segment 받음

 

**piggy backing(피기백)**

ack을 바로 보내지 않고(pending) 전송할 데이터가 있는 경우에 확인 필드('A')붙여 딸려보내는 방식

TCP에서 작동하는 ack 관리 방식은 cumulated ack이고, 

일단 ack 축적해두고 한 번에 보낼 때 segment의 ack field에 체크해서 보내는 방식이다. 

이 방식을 피기백이라고 한다.

 

 

2. 보낼 ACK이 별로 없을 때 ACK pending 발생

 

다음 seq#가 들어오면 그 #의 ACK과 함께 바로 보내준다.

 

 

3. expected sequence#를 넘어선 out-of-order 받음

 

이때는 piggy back으로 인한 ACK pending이 일어나지 않고 ACK을 즉시 내보냄

계속 해당 seq#의 data 못 받는다면 계속

"이 out-of-order seq#꺼는 보내는데 왜 내가 요청하는 seq#꺼는 안 보내?"라고 재촉하는 거다.

("duplicate ACK")

 

 

4. gap 채움

 

gap을 채운다는 것은 gap 발생 지점 이후것부터 차례대로 채워진다는 뜻이다.

gap 채울 때는 ACK pending 일어나지 않고 바로 ACK 보낸다.

 

 

 

TCP retransmission scenarios

 

다음과 같은 문제가 발생해도 알아서 잘 해결해 문제가 발생하지 않을 수 있다.

 

1. lost ACK scenario

 

ACK이 client에게 가던 중 소실됨

=> client가 server에게 ACK 보내달라고 요청 다시 보냄

but!! server측에서 다시 받은 걸 버리면 되기 때문에 비효율성이 문제가 되지 않음

 

 

2. premature timeout

 

 

ACK이 전달되는 도중에 timeout 발생해서 요청 다시 보냄

=> 다시 보낸 요청에 대한 ACK 받기 전에 원래 ACK이 뒤늦게 도착

 

이전에 재요청에 대한 ACK 보냈으므로 모두 처리된 이후의 ACK을 다시 한 번 보내준다.

=> 이전에 들어온 ACK 번호(SendBase)보다 클 경우에만 업데이트하는데 이 경우에는 이전 ACK과 번호(SendBase)와 같기 때문에 업데이트 안 해도 됨

 

 

 

3. cumulative ACK covers for earlier lost ACK

 

이전 ACK이 안 왔어도 다음 ACK 오면 불필요한 retransission 하지 않음

 

 

 

TCP fast retransmit

 

time-out 시간이 너무 길면 resending 하는 데 시간이 오래 걸리기 때문에

보완책으로 duplicate ACK 이 발생하면 그거에 해당하는 요청 다시 보냄

 

1&2: 5,6번까지 in-order로 들어와 있는 상황에서 => "7번 받고 싶어"라는 정상적인 ACK

3: 10번이 out-of-order로 들어왔다. => "7번 받고 싶어"라는 duplicate ACK

4: 8번이 들어왔다. => "7번 받고 싶어"라는 duplicate ACK

4': 9번이 들어왔다. => "7번 받고 싶어"라는 duplicate ACK