"TCP가 신뢰성을 보장하기 위해 어떻게 할까요?"
이번 글은 TCP 제어 방법에 대해 정리한 글입니다.
아래의 내용은 "기술 면접 대비 CS 전공 핵심 요약집"의 내용을 공부하고 정리한 내용입니다.
TCP는 신뢰성을 보장하기 위해 어떻게 할까요?
TCP 제어 방법
TCP는 신뢰성을 보장하기 위해 흐름 제어, 혼잡 제어, 오류 제어를 합니다.
흐름제어가 뭘까요?
흐름 제어
흐름 제어는 송신부와 수신부 사이에 생기는 데이터 처리 속도의 차이로 인해 생기는 데이터 손실을 방지하는 방법입니다.
쉽게 말해, 이름 그대로 흐름을 제어하는 것입니다.
흐름제어의 방법은 뭐가 있을까요?
흐름제어 방법은 크게 정지 대기(stop-wait), 슬라이딩 윈도우(sliding window) 방식이 있습니다.
정지 대기(stop-wait)
송신부에서 수신부로 데이터를 보낸 후, 송신부는 수신부로부터 ACK 메시지를 받을 때까지 기다리다가 ACK 메시지를 받으면, 그때 다음 데이터를 보내는 방식입니다.이 방식은 이전 메시지에 대한 응답을 받아야만 다음 메시지를 보낼 수 있다는 부분에서 시간적인 비용이 많이 든다는 단점이 있습니다.
이 방식은 아래 그림과 같이 진행됩니다.
만약, 송신부가 ACK 메시지를 오랜시간 동안 전달받지 못하면 어떻게 될까요?
송신부에서 응답받지 못했던 패킷을 재전송합니다.
정지 대기 방식은 시간적인 면에서 효율적이지 않습니다. 그렇다면, ACK를 기다리지 않고, 보내면 되지 않을까요?
슬라이딩 윈도우(sliding window)
송신부에서 데이터의 수신 여부(ACK)를 확인하지 않고 수신부에 설정한 윈도우 크기만큼 데이터를 연속적으로 보낼 수 있게 해서 데이터 흐름을 동적으로 제어하는 방식입니다. 윈도우 크기는 응답과 상관 없이 보낼 수 있는 데이터의 최대 개수를 의미합니다.
이 윈도우는 3-way 핸드 셰이킹 과정에서 정해집니다.
윈도우 크기를 N이라고 가정했을때, ACK 메시지를 받지 않은 상태로 N개의 데이터를 보낼 수 있습니다.
n+N-1개부터 n개까지 N개의 데이터를 보낸 후, 수신부에서 ACK 응답을 받게되면,
n부터 n+N번까지 데이터를 보낼 수 있게 됩니다. 마치, N개의 크기의 윈도우가 한칸씩 이동하는 것과 같아서 슬라이딩 윈도우 방식이라고 합니다.
윈도우가 4인 상황을 가정하면, 아래 그림과 같이 동작합니다.
위 그림이 나타내는 상황은 다음과 같습니다.
(단, 무조건 윈도우 크기만큼 데이터를 보내진 않습니다.)
- 송신부에서 데이터 1과 2를 보내고 3과 4를 보낼 수 있지만, 아직 보내지 않았습니다. (윈도우 범위 1 ~ 4)
- 수신부에서 데이터 1과 2를 받았다는 ACK메시지를 송신부로 보냅니다.
- 송신부에서 ACK메시지를 받고, 윈도우를 2칸 이동합니다. (윈도위 범위 3 ~ 6)
- 송신부에서 데이터 3,4,5를 보냅니다.
- 수신부에서 데이터 3과 4를 받았다는 ACK메시지를 보냅니다.
- 송신부에선 데이터 5에대한 ACK메시지는 받지 못했으므로, 윈도우를 3칸 이동합니다. (윈도우 범위 5 ~ 8)
흐름 제어에 대해 알아봤습니다. 혼잡 제어란 뭘까요?
혼잡 제어
송신부의 데이터 전달 속도와 네트워크 속도 차이로 인해 발생하는 데이터 손실을 방지하기 위한 방법입니다.
혼잡이란 무엇일까요?
혼잡은 네트워크에 패킷 수가 과도하게 증가하는 증상을 의미합니다. 혼잡이 발생해 네트워크에 패킷이 쌓이게 되어 송신부에서 일정 시간동안 응답을 받지 못하는 경우 송신부에선 메시지 전송에 실패했다고 판단을 하고, 패킷을 재전송합니다. 이는 혼잡을 더 가중시키게 됩니다.
어떻게 혼잡을 제어할 수 있을까요?
TCP는 혼잡 윈도의 크기를 조절하는 방식인 AIMD(Additive Increase Multiplicative Decrease), 느린시작(slow start), 혼잡 회피(congestion avoidance), 빠른 회복(fast recovery), 빠른 재전송(fast retransmit) 5가지 방법으로 혼잡을 제어합니다.
혼잡 윈도우 크기가 무엇일까요?
네트워크 혼잡을 방지하기 위해 TCP가 동적으로 조절하는 윈도우 크기입니다.
AIMD(Additive Increase Multiplicative Decrease)
데이터를 전달시 합 증가(Additive Increase) 방식으로 혼잡 윈도우의 크기를 조절합니다.
데이터 손실이 발생하는 경우, 혼잡 윈도우의 크기를 곱 감소(multiplicative decrease) 방식을 적용해 0.5배의 배수 단위로 줄입니다.
AIMD 방식은 여러 송신부 간에 네트워크 대역폭을 공평하게 사용할 수 있다는 점이 있는 반면, 데이터 유실이 발생하는 경우 윈도우 크기가 증가 폭 대비 감소폭이 크기 때문에 네트워크 대역폭을 넓게 사용하기 까지 시간이 오래 걸린다는 단점이 있습니다.
느린 시작(slow start)
윈도우 크기가 1인 상태에서 시작해 ACK메시지를 수신할 때마다 윈도우 크기를 1씩 늘려가고, 혼잡이 발생하게 되는 경우 윈도우 크기를 1로 줄이는 방식입니다.
송신부가 수신부로부터 1개 패킷에 대한 ACK 응답 메시지를 받은 경우, 그 다음엔 송신부에서 2개의 패킷을 보낼 수 있습니다. 2개의 패킷을 보내고, 보낸 2개의 패킷에 대해 ACK 메시지를 받은 경우엔 패킷 4개를 보낼 수 있게 됩니다. 지수 함수의 형태로 보낼 수 있는 패킷의 갯수를 증가시킵니다.
흐름은 아래의 그림과 같습니다.
패킷을 처음에 최대한 많이 보내는 것이 아니라, 1개부터 점차 늘려가는 방식이므로 느린 시작방식으로 불립니다.
전송 가능한 패킷 수를 지수 함수 형태로 늘리는 점은 AIMD 방식처럼 합증가 방식의 단점인 초기 전송 가능한 패킷 수가 적은 점을 보완하게 됩니다.
지수 함수 형태로 윈도우 크기를 늘리는 것이 정말 좋을까요? 늘리기만 한다면, 네트워크 혼잡을 유래하지 않을까요?
혼잡 회피(congestion avoidance)
윈도우 크기가 지수 함수 형태로 증가하다가 혼잡이 발생하는 것을 방지하기 위해 윈도우 크기에 대한 임계점을 정하는 방식입니다.
말 그대로 윈도우 크기가 임계점에 도달한 경우 윈도우의 크기를 선형적으로 증가하게 합니다.
ACK 메시지를 받지 못해 타임 아웃이 발생하는 시점에서 윈도우 크기의 절반을 임계점으로 설정하고, 윈도우 크기를 초깃값으로 변경합니다.
빠른 회복(fast recovery)
혼잡이 발생하는 경우 혼잡 윈도우 크기를 절반으로 줄인 후 선형적으로 증가하는 방식입니다.
혼잡이 처음 발생하는 경우엔 AIMD 방식으로 동작합니다.
AIMD랑 빠른 회복이랑 어떤 점이 다를까요?
AIMD는 패킷 손실 발생 후 Slow Start로 돌아갈 수 있어 회복 속도가 느립니다. Fast Recovery는 AIMD보다 빠르게 회복하기 위해 Slow Start로 돌아가지 않고, 혼잡 윈도우를 절반으로 줄인 후 선형적으로 증가하는 방식입니다.
AIMD랑 slow start는 다른 방식 아닌가요?
AIMD와 Slow Start는 다른 방식이지만, TCP 혼잡 제어에서 함께 사용됩니다.
Slow Start는 초기 연결 시 빠르게 증가하는 방식 (지수 증가)과 AIMD는 네트워크 부하를 조절하면서 서서히 증가하는 방식 (선형 증가 + 혼잡 시 절반 감소)을 사용합니다. 이로인해, Slow Start에서 AIMD로 전환하는 것이 일반적인 TCP 동작 방식입니다. 즉, AIMD와 Slow Start는 완전히 다른 개념이지만, TCP 혼잡 제어에서는 함께 사용되는 과정입니다.
빠른 재전송(fast retransmit)
Duplicate ACK가 3번 발생하는 경우 해당 시점의 윈도우 크기를 1/2로 줄입니다. 그뒤, ACK 메시지를 받는 경우 다시 윈도우 크기를 늘리는 방식입니다. Duplicate ACK가 3번 발생한 경우, 혼잡이 발생했다고 판단해 윈도우 크기를 조정합니다.
Duplicate ACK가 뭘까요?
패킷이 순서대로 도착하지 않아서 받아야 할 차례의 패킷을 ACK 메시지와 함꼐 요청하는 것을 말합니다.
예시로, 송신부에서 패킷을 0~5까지 보냈지만, 수신부에선 패킷 2가 오지 않은 상황입니다. 수신부는 3,4,5패킷에 대한 응답으로 2패킷을 보내라는 메시지를 담아서 응답합니다. 이 응답이 3번 반복되면 송신측에서는 패킷 2를 재전송 합니다. 또한, 3번 응답이 온 시점을 기준으로 윈도우 크기를 0.5배 합니다.
혼잡 제어 정책에 대해서 조금 더 깊게 알아볼까요?
혼잡 제어 정책
TCP는 혼잡 제어 방식을 하나만 고수하는 것이 아닌, 여러 방법을 합쳐서 혼잡 제어 정책을 사용합니다.
혼잡 발생시 윈도우 크기를 줄이거나 유지해서 혼잡을 회피하려고 합니다.
혼잡 제어 정책은 TCP Tahoe, TCP Reno, New Reno, Cubic등과 같은 혼잡 제어 정책이 있습니다. 이중 TCP Tahoe와 TCP Reno가 대표적으로 사용하는 정책입니다. 두 방식 모두 느린 시작 방식을 사용하다 임계점을 넘어가는 경우 AIMD 방식으로 전환하게 됩니다.
이 때의 임계점은 느린 시작 방식의 임계점을 의미해서 ssthresh(slow start threshold)라고 합니다.
TCP Tahoe란 뭘까요?
TCP Tahoe
초반에 느린 시작을 사용해 혼잡 윈도우 크기를 지수적으로 키웁니다. 그러다가 혼잡이 발생했다고 판단이 되는 경우 윈도우 크기의 절반을 임계점으로 설정하고 혼잡 윈도우 크기를 초기화 합니다.
TCP Tahoe는 아래 그림과 같이 동작합니다.
- slow start 방식으로 혼잡 윈도우의 크기를 지수적으로 키웁니다.
- 지수적으로 키우다가 sshthresh인 4에 도달하는 경우 AIMD 방식을 사용해 혼잡 윈도우 크기를 선형적으로 키웁니다.
- 혼잡 윈도우 크기가 선형적으로 커지다가 크기가 6이 된 경우, 3 Duplicate ACK가 발생합니다. 이로 인해 혼잡 윈도우 크기를 1로 초기화 하고 ssthresh값을 혼잡이 발생한 크기의 6의 절반인 3으로 줄입니다.
- 윈도우 크기가 4일 때 타임 아웃이 발생하면서, 윈도우 크기를 1로 초기화 하고 ssthresh 값을 2로 변경하게 됩니다.
TCP Reno
TCP Tahoe와 동일하게 초반엔 느린 시작을 사용하지만, 3 Duplicate ACK와 타임아웃을 구분해 대응합니다.
3 Duplicate ACK가 발생하는 경우 혼잡 윈도우 크기를 절반으로 줄이고, 줄인 혼잡 윈도우 크기를 ssthresh값으로 설정합니다.
타임 아웃이 발생하는 경우엔 TCP Tahoe와 마찬가지로 혼잡 윈도우 크기를 1로 초기화 합니다. 이때 ssthresh값은 변경하지 않습니다.
- 혼잡 윈도우 크기를 slow start 방식으로 지수적으로 키웁니다.
- ssthresh값인 4에 도달할 경우 AIMD방식으로 혼잡 윈도우 크기를 선형적으로 키웁니다.
- 혼잡 윈도우 크기가 6에 도달한 경우 3 Duplicate ACK가 발생해 혼잡 윈도우 크기를 절반으로 줄이고, ssthresh 값도 혼잡 윈도우 크기와 동일하게 설정합니다.
- 혼잡 윈도우 크기가 5가 되었을때, 타임아웃이 발생하면 ssthresh값은 유지하지만, 혼잡 윈도우 크기는 1로 줄입니다.
- 혼잡 윈도우 크기는 지수적으로 증가하다가 ssthresh 값인 3에 도달하면 선형적으로 증가합니다.
혼잡 제어를 알아봤습니다. 오류 제어는 어떻게 할까요?
오류 제어
통신 중에 데이터 오류 또는 유실이 발생하는 경우 데이터의 신뢰성 보장을 위해 오류를 제어하는 방식입니다.
오류 또는 유실을 어떻게 알 수 있을까요?
- 수신부에서 잘못된 데이터를 받았다는 응답인 NAK(Negative Acknowledge) 메시지를 보낸 경우
- 3 Duplicate ACK가 발생한 경우
- 수신부로부터 ACK 메시지를 받지 못해 타임아웃이 발생한 경우
TCP는 이러한 오류 또는 유실이 발생하는 경우 어떻게 오류 제어를 할까요?
오류를 제어하는 방식에는 정지대기, Go-Back-N ARQ, Selective-Repeat ARQ 방식이 있습니다.
정지 대기(stop-wait)
타임아웃이 발생하는 경우 해당 패킷을 다시 보내는 방식입니다.
흐름 제어에 나온 방식으로 데이터 유실을 간단히 처리할 수 있어서 오류 제어에도 사용됩니다.
이 방식은 ARQ(Automatic Repeat Request)이며, 데이터 전송 중 오류가 발생하면 해당 데이터를 다시 요청하여 전송하는 방식입니다.
즉, 정지 대기 방식은 ARQ방식의 하나입니다.
Go-Back-ARQ
송신부에서 연속적으로 데이터를 보내는 경우, 누락된 데이터가 있으면 송신부에서 해당 데이터부터 재전송하는 방식입니다.
- 송신부에서 패킷 0~2까지 보냅니다.
- 0~2번 패킷까지 전달받은 수신부는 ACK 3 메시지를 보냅니다.
- 송신부는 3~5번 패킷을 수신부로 보냅니다.
- 수신부는 4번 패킷을 받지 못해 ACK 4 메시지를 보냅니다.
- 송신부에서 ACK 4메시지를 받게 되면, 송신부는 이전에 보냈던 4번 패킷을 포함한 4~5번 패킷을 재전송합니다.
누락된 데이터만 보내면, 더 효율적이지 않을까요?
Selective-Repeat-ARQ
송신부에서 연속적으로 데이터를 보내는 경우, 누락된 데이터가 발견되면 수신부에서 해당 데이터만 재전송을 요청하는 방식입니다.
- 수신부에서 패킷 0~2까지 잘 수신하면 패킷 3을 보내라는 의미로 ACK 3메시지를 보냅니다.
- ACK 메시지를 수신받은 송신부에서 패킷 3~5까지 보냅니다.
- 수신부에서 패킷 4를 받지 못해서, 패킷 4를 보내라는 의미로 ACK 4 메시지를 보냅니다.
- 송신부는 ACK 4 메시지를 받은 후, 4번 패킷을 수신부로 보냅니다.
- 수신부는 4번 패킷을 받고, ACK6 메시지를 송신부에 보내 6번 패킷부터 보내도록 요청합니다.
누락된 특정 패킷만 재전송하는 점이 효율적일 수는 있지만, 받은 패킷을 수신부 측에서 재정렬해야 한다는 점이 존재합니다.
정리
- TCP는 신뢰성을 보장하기 위해 흐름 제어, 혼잡 제어, 오류 제어를 사용하며, 이를 통해 패킷 손실 및 네트워크 혼잡을 방지합니다.
- 흐름 제어는 송신부와 수신부 간의 데이터 처리 속도 차이를 조정하며, 정지 대기(Stop-and-Wait)와 슬라이딩 윈도우(Sliding Window) 방식이 사용됩니다.
- 혼잡 제어는 네트워크의 패킷 과부하를 방지하기 위해 혼잡 윈도우 크기를 조절하며, AIMD, 느린 시작(Slow Start), 혼잡 회피(Congestion Avoidance), 빠른 회복(Fast Recovery), 빠른 재전송(Fast Retransmit) 등의 방법을 적용합니다.
- 오류 제어는 데이터 손실 및 오류 발생 시 재전송을 통해 신뢰성을 유지하며, 정지 대기 ARQ, Go-Back-N ARQ, Selective Repeat ARQ 방식이 사용됩니다.
- TCP 혼잡 제어 정책으로는 TCP Tahoe와 TCP Reno가 있으며, 느린 시작과 AIMD 방식을 결합하여 혼잡 발생 시 윈도우 크기를 조정하고 효율적인 데이터 전송을 보장합니다.
'CS' 카테고리의 다른 글
프로세스와 스레드 (2) | 2025.02.12 |
---|---|
[DB] 트랜잭션 (0) | 2025.02.09 |
[네트워크]TCP/IP & HandShaking (0) | 2025.02.01 |
[네트워크] OSI 7계층 (2) | 2025.01.27 |
[운영체제] 스케줄링 (0) | 2024.11.26 |