본문 바로가기
Infra & Security Eng/Network & Security

TCP 개념 정리 (seq, ack, 재전송, 흐름 제어, 혼잡 제어)

by 엔지니어 E 2026. 2. 19.
반응형

Seq, ACK

Seq, ACK
컴퓨터가 데이터를 보낼 때 두가지 중요한 숫자를 적어서 보낸다
- Seq(Sequence Number): 내가 보내는 이 데이터의 시작 번호는 이거야 라고 알려주는 것
- ACK(Acknowledgment Number): 네가 보낸 거 잘 받았어. 이제 그 다음 번호인 이걸 보내줘 라고 요청 하는 것

그림 해설 (컴퓨터 두 대가 서로 데이터를 주고 받을때, 길을 잃지 않도록 번호를 붙이는 규칙에 대한 설명 )
1. 첫 번째 화살표(Host A -> Host B)
- A가 C라는 글자 하나를 보낸다 

- 이 때 자기 번호는 42라고 했고, 상대방에게 79번을 달라고 한다 
* Host A는 42번 데이터를 보냈으니, 다음에는 43번을 보낼 준비를 한다 

2. 두 번째 화살표(Host B -> Host A):

- B가 C를 잘 받았다고 답장한다 
- A가 79번을 달라고 했으니 자기 번호를 79로 해서 보낸다 
- A가 아까 42번(글자 1개)를 보냈으니 B는 "잘 받았어, 이제 43번 줘"라고 한다 

3. 세 번째 화살표(Host A _> Host B)
- A가 다시 답장한다. B가 43번을 달라고 했으니 자기 번호를 43번으로 적는다
- B가 아까 79번을 보냈으니 , A는 "잘 받았어. 이제 80번을 줘" 라고 한다 

 

TCP: RTT와 Timeout 설정 원리 

1. Timeout(타임아웃) 이란? 
데이터를 보낸 후, 상대방의 응답(ACK)이 올 때까지 기다리는 제한 시간 
- 설정 기준: 기본적으로 RTT(데이터가 한 바퀴 돌아오는 시간)보다 커야 한다 
- 너무 짧게 설정 하면? 상대방이 잘 받았는데도 응답이 오기 전에 다시 보내버리는 불필요한 재전송이 발생 한다
- 너무 길게 설정 하면? 실제로 데이터가 사라졌을 때 다시 보내기까지 너무 오래 걸려 대응이 늦어진다 

2. RTT(Round Trip Time) 측정 방법
SampleRTT: 데이터를 보낸 시간부터 응답(ACK)이 도착할 때까지 걸린 실제 시간 간격 
* 내가 측정한 샘플 RTT

3. EstimatedRTT(추정 RTT) 계산
실제 통신 환경에서는 SampleRTT가 매번 바뀌기 때문에, 이를 더 부드럽고 안정적으로 만들기 위해 EstimatedRTT를 사용 한다
* 가중 평균 사용: 이전에 계산된 값과 새로 측정한 SampleRTT를 일정한 비율로 섞어 평균을 낸다  

* RTT는 우리말로 **'왕복 시간'**이라고 부른다. 말 그대로 패킷(데이터 뭉치)이 내 컴퓨터를 출발해 목적지(서버)에 도착하고, 그에 대한 응답이 다시 나에게 돌아오기까지 걸리는 총 시간을 의미 한다

 

EstimatedRTT (예상소요시간) 계산 공식

EstimatedRTT = (1 - alpha) * EstimatedRTT + alpha * SampleRTT

과거의 평균값과 현재 측정된 값을 일정한 비율로 섞어서 계산한다

지수 가중 이동 평균: 최근 측정값일수록 더 많이 반영하고, 오래된 데이터의 영향력은 지수적으로 빠르게 감소하게 만드는 방식
일반적인 설정값: 보통 알파 값은 0.125 를 사용

 

Timeout 설정 공식

timeout 설정 
EstimatedRTT보다 약간의 여유값을 더한 값으로 설정 

DevRTT
네트워크가 얼마나 불안정한지를 나타내는 수치로 실제 측정값(SampleRTT)이 평균(EstimatedRTT) 에서 얼마나 벗어나 있는지 계산한 예측치 

공식


* 베타 권장값: 0.25

 

TCP 데이터 전송 시 일어나는 일

컴퓨터가 상대방에서 데이터를 보낼 때는 세 가지 상황에 맞춰 행동한다 

1. 데이터를 처음 보낼 때(App으로부터 data 수신)
- 번호 붙이기: 보낼 데이터에 순서대로 번호를 붙인다
- 시간 재기: 데이터를 보내자마자 타이머를 켠다
- 기다리기: 미리 정해둔 시간(Timeoutlnterval) 동안 상대방의 대답을 기다린다

2. 기다려도 대답이 없을 때(timeout)
- 다시 보내기: 정해진 시간이 다 지나도록 대답이 없으면 , 방금 보낸 데이터를 똑같이 다시 보낸다 
- 시간 다시 재기: 다시 보냈으니까 타이머도 처음부터 다시 시작한다 

3. 잘 받았다는 대답이 왔을때(ACK 수신)
- 확인하기: 상대방이 보낸 대답의 번호를 확인한다 
- 목록 지우기: 상대방이 잘 받았다고 확인해준 번호는 "성공"목록으로 옮긴다 
- 타이머 처리: 아직 상대방이 대답하지 않은 다른 데이터가 남아 있다면 타이머를 다시 시작하고, 모든 대답을 다 받았다면 타이머를 끈다 

[특별규칙] 빠른 재전송
상황: 똑같은 번호의 대답(중복 ACK) 이 3번 연속으로 도착 했을 때 
의미: 상대방이 아직 20번을 못 받아서 게속 20번을 달라고 눈치 채는 것 
동작: 2번(Timeout) 시간이 다 되기 전이라도, 즉시 그 데이터를 다시 보낸다 

 

TCP : 받는 쪽(Receiver)의 ACK 생성 규칙

1. 순서대로 잘 왔을때(지연된 ACK) 
상황: 기다리던 번호의 데이터가 도착 했고, 그 이전 번호들도 이미 다 받은 상태이다 
동작: 즉시 답장하지 않고 500ms(0.5초) 동안 그 다음 데이터가 오는지 기다린다. 만약 오지 않으면 그때 ACK를 보낸다 

2. 연속해서 잘 왔을때(누적된 ACK)
상황: 기다리던 번호의 데이터가 왔는데, 아직 앞의 데이터에 대한 답장(ACK)을 안 보낸 상태에서 또 데이터가 온 경우 
동작: 하나하나 답장하지 않고, 하나의 누적된 ACK 를 보내서 한꺼번에 확인해 준다 

3. 중간에 번호가 빠졌을때(중복된 ACK)
상황: 기다리던 번호보다 더 높은 번호의 데이터가 먼저 도착해서 중간에 빈 공간(Gap) 이 생긴 경우이다
동작: "나는 아직 이 번호(빠진 번호)를 기다리고 있어!" 라고 알려주는 중복된 ACK를 보낸다 

4. 빠졌던 번호가 도착했을 때 
상황: 위에서 발견된 빈 공간을 채워줄 데이터가 도착한 경우 이다 
동작: 빈 곳이 채워졌으므로 즉시 ACK를 보내서 어디까지 잘 받았는지 알려준다 

 

TCP 흐름 제어(Flow Control)

1. 흐름 제어란? 
정의: 데이터를 보내는 쪽(Sender) 이 받는 쪽(Receiver)의 저장공간(Buffer)이 넘치지 않도록 보내는 속도를 조절 하는 것 
목적: 받는 쪽의 컴퓨터 프로그램이 데이터를 읽는 속도와 보내는 쪽의 전송 속도를 맞추기 위해 

2. 저장 공간의 구성(RcvBuffer) 
RvcBuffer = TCP data + RcvWindow(여유 공간) 

받는 쪽의 컴퓨터에는 데이터를 임시로 담아주는 전체 바구니(RcvBuffer)가 있다 
TCP data: 이미 도착해서 바구니에 들어있는 데이터 
RcvWindow(여유 공간): 아직 비어 있어서 데이터를 더 담을 수 있는 남은 공간 

3. 작동 원리 
1) 공간 알리기: 데이터를 받는 쪽은 자기 바구니에 남은 공간(RcvWindow size)이 얼마나 되는지 상대방에게 계속 알려준다 
2) 속도 조절: 보내는 쪽은 상대방이 상대방이 알려준 남은 공간(RcvWindow) 보다 적은 양의 데이터만 보낸다 
3) 결과: 이렇게 하면 받는 쪽의 바구니가 꽉 차서 데이터가 넘쳐 흐르는(Overflow) 일을 막을 수 있다  

 

Three-way handshake

1. 연결 시작하기(Three-way handshake)
컴퓨터끼리 데이터를 주고받기 전, 준비를 마치는 과정 이다 

Step1: 클라이언트가 서버에게  SYN 신호를 보낸다 
- 시작 숫자(seq#)를 정하고, 진짜 데이터는 아직 안 보낸다 

Step2: 서버는 신호를 받고 SYNACK를 보낸다 
- 서버가 변수와 저장 공간(buffer)을 만들고, 자기 숫자(seq#) 를 정한다

Step3: 클라이언트가 ACK 신호를 보낸다 
- 클라이언트도 변수와 저장 공간을 만들며, 이제부터는 데이터를 같이 보낼 수 있다

2. 연결 종료하기(Closing a connetcoin)
할 일을 다 마친 후 , 안전하게 연결을 끊는 과정 이다 

Step1: 클라이언트가 FIN bit 를 1로 설정해서 보낸다 
- "이제 그만할래"라는 신호 이다 

Step2: 서버는 ACK를 보내 확인하고, 자신도 FIN을 보낸다 
- "알았어, 나도 이제 끝낼게"라는 응답이다 

Step3: 클라이언트는 서버의 FIN을 받으면 ACK를 보낸다 
- 그 후 일정 시간(time wait)을 기다렸다가 연결을 완전히 닫는다 

Step4: 서버는 클라이언트의 ACK를 받으면 연결을 종료한다

 

TCP 혼잡제어(Congestion Control)

1. 혼잡(Congestion) 이란?
정의: 너무 많은 곳에서 한꺼번에 많은 데이터를 보내려고 해서 데이터가 지나가는 길(네트워크)이 꽉 막힌 상태 이다 
현상: 길이 막히면 데이터가 사라지거나(pkt 손실), 도착하는 시간이 아주 오래 걸리게 된다(지연 증가)

2. 흐름제어와의 차이점
흐름제어: "받는 사람"의 저장 공간이 부족할까 봐 조절 하는 것 
혼잡제어: "데이터가 지나가는 길" 이 막힐까봐 조절 하는 것 

3. 어떻게 조절할까요?(Sender의 역할)
보내는 쪽(Sender)은 길의 상태를 직접 눈으로 볼 수 없기 때문에 다음과 같은 신호를 보고 눈치껏 데이터의 양을 줄인다 

양을 줄여야 할때
- 타이머가 자주 울릴 때 
- 데이터를 다시 보내는 양(재전송량)이 갑자기 많아질 때