테마
TCP 신뢰성과 흐름제어
TCP의 신뢰성과 흐름제어
TCP는 수신 측의 상태를 계속 확인하면서 데이터를 전송하는 신뢰성 지향 프로토콜이다. 상대방이 받을 수 없으면 전송량을 줄이거나 멈춘다. 반면 UDP는 이런 상태 확인 절차를 최소화한 단순한 전송 방식이다.
이 배려가 TCP의 신뢰성을 만들어 내지만, 동시에 내부 구조를 복잡하게 만드는 원인이기도 하다.
ACK(Acknowledgement): 잘 받았다는 확인
TCP는 데이터를 보내면 상대방이 **잘 받았다는 확인(ACK)**을 보내도록 설계되어 있다.
ACK 번호의 의미가 중요하다. ACK 3은 "1번과 2번까지 잘 받았으니, 다음에 3번을 보내달라"는 뜻이다. 이것을 **누적 ACK(Cumulative ACK)**라고 한다.
실제로는 시퀀스 번호가 1, 2, 3이 아니라 바이트 수만큼 증가한다. 1460 bytes를 보냈다면 다음 시퀀스는 +1460이 된다.
Window Size: 수신 측의 여유 공간
수신 측에는 TCP 입출력을 위한 버퍼(Buffer) 메모리가 있다. 네트워크에서 데이터가 도착하면 이 버퍼에 쌓이고, 애플리케이션(프로세스)이 버퍼에서 데이터를 꺼내간다.
이 여유 공간의 크기를 **Window Size(윈도우 사이즈)**라고 한다. ACK를 보낼 때 이 Window Size도 함께 전달된다. 송신 측은 수신 측의 Window Size를 보고 데이터를 보낼지 말지 결정한다.
5가지 대표적 TCP 장애 유형
TCP 통신에서 발생할 수 있는 대표적인 장애 유형은 5가지이다. 각 유형의 원인이 네트워크인지 **엔드포인트(애플리케이션)**인지를 구분하는 것이 장애 대응의 핵심이다.
1. Lost Segment (패킷 유실)
네트워크 유통 과정에서 세그먼트가 아예 사라진 경우이다. 물류센터에서 택배를 분실한 것과 같다. 100% 네트워크 원인이다.
2. Retransmission (재전송)
송신 측이 ACK를 일정 시간 동안 받지 못하면 해당 세그먼트를 다시 보낸다. 재전송 타이머(일반적으로 약 1~3초)가 만료되면 발동된다.
3. Duplicate ACK (중복 ACK)
재전송 과정에서 타이밍이 어긋나면 같은 ACK가 여러 번 전달될 수 있다. 수신 측이 "3번 받았어"라고 보냈는데, 송신 측이 이미 재전송을 시작한 경우 "3번 받았어"가 두 번 이상 도착한다.
4. Out of Order (순서 뒤바뀜)
세그먼트가 1-2-4-3 순서로 도착하는 경우이다. 경로가 여러 개인 네트워크에서 패킷마다 다른 경로를 타면 발생할 수 있다. 네트워크 원인이 유력하다.
5. Zero Window (여유 공간 소진)
수신 측의 버퍼 여유 공간이 0이 된 상태이다. 네트워크 전송 속도가 애플리케이션의 처리 속도를 초과할 때 발생한다. 엔드포인트(애플리케이션) 원인이다.
재전송과 SACK(Selective ACK)
기본 ACK는 누적 방식이라 중간에 하나가 빠지면 그 이후를 전부 재전송해야 하는 비효율이 있다. 이를 개선한 것이 **SACK(Selective Acknowledgement)**이다.
SACK를 사용하면 유실된 세그먼트만 선택적으로 재전송할 수 있어 효율이 크게 향상된다.
전체 데이터 흐름 요약
- 송신 측: 파일 읽기 → 프로세스 버퍼 → 소켓 IO 버퍼 → Encapsulation → 네트워크
- 수신 측: 네트워크 → Decapsulation → 소켓 IO 버퍼 → 프로세스 버퍼 → 처리
- 네트워크는 채우고, 프로세스는 비운다 -- 이 두 작업이 동시에 일어난다
핵심 정리
- ACK는 "다음에 이 번호를 보내달라"는 누적 확인이다
- Window Size는 수신 측의 버퍼 여유 공간으로, ACK와 함께 전달된다
- 5가지 장애 유형: Lost, Retransmission, Duplicate ACK, Out of Order, Zero Window
- Lost/Out of Order = 네트워크 원인, Zero Window = 엔드포인트 원인
- SACK는 유실된 세그먼트만 선택적으로 재전송하는 개선된 ACK 방식이다
- TCP가 복잡한 이유는 신뢰성 보장을 위한 다양한 메커니즘 때문이다