우보천리 개발

[2. Transport Layer] TCP의 신뢰적인 데이터 전송 본문

Computer Science/네트워크

[2. Transport Layer] TCP의 신뢰적인 데이터 전송

밥은답 2023. 4. 29. 19:26
반응형

TCP는 UDP와 다르게 '신뢰적인 데이터 전송' 을 보장한다.

신뢰적인 데이터는 어떻게 전송되는지 우선 원리를 살펴본다.

 

1. Reliable Data Transfer(RDT)

신뢰적인 데이터 전송 서비스를 추상화하여 구현한 것이 RDT Protocol이다.

단방향으로 데이터를 전송하는 것을 가정하고, 나타날 수 있는 문제는 크게 두가지이다.

우선 Packet Error 그리고 Packet Loss 이다.

 

rdt 1.0

rdt 1.0 에서는 가장 신뢰적인 상태라고 가정하기 때문에 오류가 발생하지 않고 신뢰적이다. 그렇기 때문에

수신 측에서도 어떠한 피드백을 보내주지 않아도 된다. 


rdt 2.0

rdt2.0 에서는 비트에 오류가 있다라고 가정을 한다.

송신자와 수신자는 '긍정 확인응답'과 '부정 확인응답'과 같은 제어메시지로 오류가 있어서 재송신이 필요한지에 대해 알려준다.

 이 프로토콜에서 비트 오류를 처리하기 위해서는 3가지 기능이 필요하다; 1. 오류검출 2. 수신자 피드백 3. 재전송

 

송신자와 수신자는 '인터넷 체크섬' 필드를 통해서 오류가 있는지 없는지를 서로 알리고 송신자는 수신자로부터 ACK or NAK를 기다린다.

ACK를 받았다는 것은 오류가 없이 잘 받았다라는 의미이므로 다음 패킷을 전송한다. 만약 응답이 없다면 다음 데이터를 전송하지 않을 것이다.

그런 이유에서 rdt 2.0과 같은 프로토콜은 stop-and-wait 프로토콜이라고 한다

 

하지만.. 더 생각해보면 상대방으로부터 ACK or NAK가 손상이 되어서 도착하지 않으면 어떻게 할까?

하나의 대표적인 가능성은 송신자가 손상된 ACK or NAK를 받으면 해당 패킷을 재전송하는 duplicate Packet을 보내는 방법이다.

그렇지만 중복 패킷(duplicate)을 보낸다면 해당 패킷이 새로운 패킷인지 아니면 이전에 보낸 패킷인지 구별 할 수 없다.

 

그래서 패킷에 Sequence number을 붙인다. 이 순서번호를 무제한으로 늘리면 편하지만 필드의 크기가 그만큼 계속 커진다는 부담이 있다. 하지만 rdt 2.0 에서는 전송 후 대기 방식을 사용한다고 가정해서 0과 1만 있다면 재전송인지 아닌지 구별 할 수 있다.

 


rdt 3.0

rdt 3.0에서는 오류와 손실 둘다 있다고 가정한다. 

우선 손실에 있어서 송신된 패킷에 대한 ACK가 유실되었다면 어떻게 할까?

송신자는 보낸 패킷에 있어서 Timer를 설정하고 타이머가 끝나면 해당 패킷이 손상이 되지 않아도 다시 전송할 수 있다.

 

그러나 발생하는 문제점이 해당 패킷에 대한 타이머는 얼마나 오래 기다려야할까 이다. 

우선 타이머는 왕복시간(RTT)보다는 길어야한다. 그렇지 않다면 불필요한 재전송이 발생한다. 그렇다고 너무 길게 설정하면 전송 지연이 발생한다.


TCP 신뢰적인 데이터 전송

rdt 프로토콜에서는 기본적으로 하나의 패킷을 보내고 stop-and-wait 방식으로 가정하였다. 하지만 실제 네트워크에서 패킷을 하나씩 보내고 확인한다면 매우 비효율적일 것이다.

해결책으로는 pipelining 방식이 있다. 개별 패킷에 대해 확인응답을 기다리지 않고 여러 패킷을 한번에 보내는 것이다. 

파이프라이능의 특성상 우선 Sequence number의 범위도 커져야하고, 프로토콜 내에서 송신 Buffer와 수신 Buffer를 유지해야한다. 

이유는 패킷을 여러개를 한번에 보내기 때문에 어떤 패킷이 손실되거나 오류가 있을 경우가 있기 때문이다. 

 

TCP에서 신뢰적인 데이터 전송을 위해서 파이프라이닝, 타이머 그리고 축적 ACK(Cumulative ACKs)를 사용한다

 

<여러가지 시나리오>

1. Host A가 Host B로 세그먼트를 보낸다고 가정한다. Host A가 보낸 데이터에 대한 응답이 손실이 되었다면 Host A가 보낸 데이터의 타이머가 돌아갈 것이다. 타임아웃이 되기 전까지 응답이 오지 않는다면 A는 해당 패킷이 손실되었다고 가정하고 재전송을 할 것이다. 

 

2. 이번 시나리오에서는 Host A는 두개의 데이터를 보낸다고 가정한다. 즉 Seq=92를 가진 8바이트 데이터와 Seq=100인 20바이트 데이터이다. Host B는 두개의 데이터를 무사히 받고 A한테 ACK=100과 ACK=120(100번까지 잘 받았고, 120까지 잘 받았다는 축적 ACK)를 보낼 것이다. 하지만 ACK가 도착하기 전에 A의 Seq=92가 타임아웃이 발생하면 A는 92패킷을 다시 보낼 것이다. 

이후 B에서 온 2개의 ACK가 도착하고 마지막으로 A가 타임아웃으로 인해 송신한 패킷에 대한 ACK=120이 도착할 것이다.

여기서 ACK=120은 120번까지 문제없이 수신했다는 뜻이기 때문에 A는 그 이전 패킷을 다시 전송할 필요가 없다.

 

TCP는 이렇게 타이머와 축적된 ACK를 통해서 신뢰적인 데이터 전송을 보장한다.

 

빠른 재전송

타이머로 인한 재전송에 있어서 발생할 수 있는 문제는 타임아웃 주기가 너무 길 때도 있다는 것이다. 

송신자가 3개의 중복 확인 응답을 수신할 경우, 타임아웃이 되기 전이여도 분실되었다고 간주하여 재전송을 하게 되고 이것을 

Fast Retransmit (빠른 재전송) 이라고 한다.

 

호스트 B는 92번을 받고 (8바이트 데이터)이기 때문에 ACK=100을 보낸다. 하지만 A가 송신한 100번은 유실되었다고 가정한다.

그럼 이후에 도착하는 A가 보낸 데이터에 대해서는 B는 ACK=100으로 응답할 것이다. 100번을 기다리고 있는데 다른 순서번호가 도착하고 있기 때문이다. 이렇게 3개의 연속 중복 응답을 받은 A는 B에게 해당 순서번호의 데이터인 Seq=100을 보내게 될 것이다.

반응형
Comments