TCP 제공 서비스
✔️ 세그먼테이션/리어셈블리
✔️ 멀티플렉싱/디멀티플렉싱
✔️ 오류 검출
✔️ 신뢰 전송
✔️ 혼잡 제어
TCP 특징
✔️ point-to-point 통신
- 1:1 소켓 통신
- 소켓 주소 = 출발지 IP 주소 + 출발지 port 번호 + 목적지 IP 주소 + 목적지 port 번호
- 멀티캐스팅 지원 불가
멀티캐스팅
단일 송신 동작으로 한 송신자가 여러 수신자에게 데이터를 전송하는 것
✔️ 연결지향형
✔️ full-duplex(전이중 통신)
- 양방향 동시 세그먼트 전송 가능
- MSS(Maximum Segment Size) = 세그먼트의 데이터 필드 최대 크기(보통 1460 바이트)
- 송신 버퍼에서 MSS 단위로 송신
✔️ 바이트 스트림 전송
- 송신 프로세스가 소켓의 송신 버퍼에 전달한 바이트 스트림을 수신 소켓의 수신 버퍼에 순서대로 전송
- 송신 프로세스는 송신 버퍼의 임의의 크기의 바이트열을 write
- 수신 프로세스는 수신 버퍼에서 원하느 크기의 바이트열을 read
TCP 연결
✔️ 3-way handshaking
- 클라이언트와 서버 간에 동기화 과정
- 교환 정보 = 소켓 정보, 시작 순서 번호, 수신 윈도우 크기
✅ SYN 세그먼트
- 연결 설정을 위해 클라이언트 TCP가 서버 TCP에 전송
- 페이로드가 없는 컨트롤 세그먼트
- 제어 플래그의 SYN 비트를 1로 설정
- 시작 순서 번호(ISN) 설정
- ACK을 위해 순서 번호 1 소비(가상의 1바이트 데이터 전송)
✅ SYN+ACK 세그먼트
- SYN 세그먼트를 수신한 TCP 서버가 클라이언트 TCP에 전송
- 페이로드가 없는 컨트롤 세그먼트
- SYN 비트와 ACK 비트를 1로 설정
- 시작 순서 번호(ISN) 설정
- 확인 번호(ACK) 설정
- 수신 윈도우 크기 설정
- ACK을 위해 순서 번호 1 소비(가상의 1바이트 데이터 전송)
✅ ACK 세그먼트
- SYN+ACK 세그먼트를 수신한 클라이언트 TCP가 서버 TCP에 전송
- ACK 비트를 1로 설정
- 확인 번호(ACK) 설정
- 수신 윈도우 크기 설정
- 페이로드에 데이터 포함 가능
- 데이터 미포함시에는 순서번호 소비하지 않음
✔️ 4-way handshaking
✅ Time-wait
- 수신 TCP는 마지막 ACK을 전송하고 일정 시간(time-wait)동안 연결을 종료하지 않고 대기한다.
- 수신 TCP가 전송한 ACK이 손실되었을 경우 연결을 종료하지 않고 서버는 마지막 FIN 세그먼트에 대해서 재전송하기 떄문이다.
TCP 세그먼트
- 헤더 = Mandatory
- 데이터 = Optional
✔️ MSS
- 페이로드에 포함되는 응용 메시지 조각(Chunk)의 최대 크기
- 데이터 링크의 MTU에 의해 결정(ex: LAN MTU = 1500bytes)
- TCP 헤더 크기 + MSS + IP 헤더 크기 <= MTU
MTU(Maximum Transmission Unit)
- 버퍼 메모리 효율과 링크 사용 공정성을 위해 MTU 설정
✔️ 포트 번호
- 목적: 응용 프로세스 식별
- 클라이언트 포트는 번호 연결 설정 시에 임의의 포트 번호 할당
- 서버 포트 번호는 연결 설정 전에 잘 알려진 포트 번호로 미리 할당
- 출발지 포트 번호는 세그먼트 송신자의 포트 번호
- 목적지 포트 번호는 세그먼트 수신자의 포트 번호
✔️ 순서 번호
- 번호 부여 원칙 = 시작 순서 번호(ISN)부터 이미 송신된 바이트의 다음 바이트 번호
- ISN은 연결설정할 때 임의의 수로 설정
- 세그먼트 번호가 아님
- 세그먼트 송신자에 의해 부여
- ISM + 송신된 바이트 수
- ex) ISN = 3000, 송신된 바이트 수 = 1000 -> 순서 번호 = 4000
✔️ 확인 번호
-
번호 부여 원칙 = 순서대로 수신된 세그먼트의 마지막 바이트의 다음 바이트 번호(수신을 기대하는 세그먼트 번호)
-
순서대로 수신된 세그먼트 순서 번호 + 수신된 세그먼트 데이터 크기
- ex) 세그먼트 순서 번호 = 4000, 데이터 = 1000 -> 확인번호 = 5000
-
누적 수신 확인(accumulative ack)
✔️ 헤더 길이
헤더 필드 전체 길이(20~60바이트)를 4 바이트 워드 단위로 표시(5~15 워드)
✔️ 수신 윈도우 크기
- 수신 TCP가 수신 가능한 데이터 크기(버퍼 여유 공간)
- 수신 TCP가 ACK 세그먼트에 표시
- 송신 윈도우(Send Window) 결정
- 최대 66,535 바이트(16비트 필드)
✔️ 제어 플래그(Control flags)
- URG = urgent(데이터 중 긴급 데이터가 있을떄)
- ACK = Acknowledgement
- PSH = Push(MSS만큼 데이터가 버퍼에 찾을때 말고, 바로 버퍼에서 송신해라)
- RST = Reset(비정상 TCP 연결 해제)
- SYN = Synchronization
- FIN = Finish
✔️ 긴급데이터 포인터
긴급 데이터 포인터
TCP 재전송 타이머
✅ TCP RTT
- 세그먼트 송신 후 ACK 수신까지 걸리는 시간
- 네트워크 상태에 따라 가변적인 시간
- RTT 값을 기반으로 타이머를 설정하므로 RTT를 예측하는 것은 매우 중요
- 타이머 시간이 길면 → 대기 시간 ↑ → 링크 효율 ↓
- 타이머 시간이 짧으면 → 재전송 ↑
✅ RTT 추정
- 지수 이동 가중 평균 사용
- 추정 RTT = (1-𝝰) 추정 RTT + (𝝰 측정 RTT)
✅ RTT 분산 추정
분산 RTT = (1-β) 분산 RTT + β ⏐ 측정 RTT - 추정 RTT ⏐
✅ 재전송 타이머 값
TimeoutInterval = EstimatedRTT(추정 RTT) + 4 DevRTT(4 분산 RTT, 안전 여분)
TCP 신뢰 전송, 흐름제어
✔️ TCP 세그먼트 전송 규칙
✅ 누적 수신 확인
-
누적 수신 확인
- 누적적으로 완전하게 수신된 바이트 스트림 번호 확인
- 중복 ACK 세그먼트(이미 수신한 확인번호를 가진 ACK) 수신 가능
-
중복 ACK 수신 상황
- 순서가 바뀐 세그먼트 도착한 경우
- 중간 세그먼트 손실이 발생했을 경우
✅ 단일 타이머
누적 수신 확인이 되지 않은 가장 오래된 세그먼트에 대한 재전송 타이머 유지
✔️ 재전송 기반으로 오류 복구(신뢰 전송)
✅ 타임아웃에 의한 재전송
- 타임아웃 동안 누적 ACK 미수신 세그먼트 재전송
✅ 빠른 재전송
- 세그먼트가 손실된 상황에서 Timeout까지 불필요한 긴 시간 대기 회피
- 3개 중복 ACK이 도착하면 타임아웃과 무관하게 누적 수신 확인 다음 세그먼트 전송
Timeout 전에 중복 ACK 발생 이유
- 순서가 바뀐 세그먼트 도착
- 중간 세그먼트 손실
순서가 바뀐 세그먼트 도착
- 1~2개의 중복 ACK 후에 정상 ACK 회신
- 연속된 세그먼트의 도착 시간에 큰 차이가 없음
- 3개 이상의 중복 ACK이 발생하면 순서 문제가 아니라고 판단
중간 세그먼트 손실
- 라우터에서 경미한 버퍼 오버플로우 발생
- 오버플로우 상황이 개선되어 다음 세그먼트들은 정상 도착
✔️ 흐름 제어
개념
송신 TCP가 지나치게 많은 데이터를 한꺼번에 송신함으로써 수신 TCP의 버퍼가 넘쳐 데이터 손실이 발생하는 문제를 방지하는 메커니즘
방안
수신 TCP는 자신의 수신 버퍼 내의 여유 공간의 크기를 송신 TCP에게 통지하고, 송신 TCP는 통지된 여유 공간의 크기보다 적은 양의 데이터를 송신
✅ 수신 윈도우(Receive Window, rwnd)
수신 버퍼내의 여유 공간의 크기
수신 윈도우 변화
- 연결 설정 시에 수신 버퍼 크기와 동일하게 설정
- 수신 데이터의 버퍼 저장과 응용 프로세스에 의한 버퍼 데이터 읽기 과정에서 수신 윈도우 변화
수신 윈도우 통보
수신 TCP가 통신 TCP로 전달하는 세그먼트의 수신 윈도우 필드에 포함되어 통보
흐름 제어
- 마지막으로 송신한 바이트 번호와 확인 세그먼트를 통해 마지막으로 수신확인된 바이트 번호의 차이가 항상 수신 윈도우보다 작게 유지
- 마지막 송신 번호 - 마지막 ACK 번호 <= 수신 윈도우
- LastByteSent - LastByteAcked <= rwnd
rwnd가 0일때
- 송신 TCP는 더이상 데이터를 기다리지 않고 수신 TCP로부터 변경된 수신 윈도우가 도착하기를 기다리고
- 수신 TCP는 송신 TCP로 전송할 확인 세그먼트가 없어 수신 윈도우 변화를 통보하지 못하는
- 데드락 상태 진입
➜ 윈도우 프로브 세그먼트
- 수신 윈도우가 0일 때, 송신 TCP가 수신 TCP에게 주기적으로 전송하는 1바이트 세그먼트
- 수신 TCP는 프로브 세그먼트에 대한 확인 세그먼트를 통해 수신 윈도우 정보를 수신
TCP 혼잡 제어
✔️ 네트워크 혼잡 제어 원리
네트워크 혼잡
트래픽 증가로 인해 라우터/스위치 버퍼의 큐잉 지연시간 증가 및 오버플로우 발생
TCP 네트워크 혼잡 인식
심각한 혼잡: 타임아웃 발생
경미한 혼잡: 중복 ACK 발생(3 duplicate acks)
혼잡 제어 원리
세그먼트 전송률 축소 조정 → 네트워크로 유입되는 트래픽 감출
트래픽 증가로 인해 라우터/스위치 버퍼의 큐잉 지연시간
혼잡 제어 TCP 전송률 제어
마지막 송신 바이트번호 - 마지막 수신 확인 바이트 번호 ≦ min(수신 윈도우, 혼잡 윈도우)
✔️ 1. 슬로우 스타트(exponential increase)
- 연결 시작 또는 혼잡 발생 시에 혼잡 윈도우(cwnd)를 최솟값부터 전송률을 낮게 천천히 시작
- ACK이 수신될 때 때마다 혼잡 윈도우를 1씩 증가
- ACK 수신 → cwnd = cwnd + 1
- RTT마다 혼잡 윈도우를 2배씩 증가(지수적 증가)
✔️ 2. 혼잡 회피(Additive increase)
- 슬로우스타트 구간에서 혼잡윈도우는 지수적으로 증가
- 혼잡 윈도우가 임계치(
ssthresh
)에 도달하거나 넘어가면 선형적으로 증가하도록 증가 속도율을 조절하는 알고리즘
- RTT마다 혼잡 윈도우를 1씩 증가(선형 증가)
- ACK이 수신될 때마다 혼잡윈도우를 (1/cwnd) 씩 증가
- ACK 수신 → cwnd = cwnd + (1/cwnd)
✔️ 3. 빠른 복구
✅ 적용
- 경미한 혼잡 상황(3개의 중복 ACK에 의한 빠른 재전송)에 적용
- 정상 ACK이 수신되어 오류 복구가 완료되면 슬로우 스타트 구간을 뛰어넘고 혼잡 회피 단계로 진입
✅ 알고리즘
- 임계치를 현재 혼잡 윈도우의 ½로 지정(ssthresh = cwnd/2)
- 손실된 세그먼트 재전송
- 혼잡 윈도우를 임계치 +3 으로 설정(cwnd = ssthresh+3)
- 여전히 중복 ACK을 수신하면 CWND = CWND+1, 새로운 세그먼트 추가 전송 가능
- 정상 ACK을 수신하면 CWND = ssthresh, 혼합 회피 단계로 진입
✅ AIMD
Additive Increase Multiplicative Decrease
TCP 버전
✔️ Tahoe
중복 ACK 발생 시 혼잡 윈도우를 1로 설정한다.
알고리즘
- 임계치를 현재 혼잡윈도우의 ½로 설정
- 슬로우 스타트 개시(혼잡 윈도우=1로 설정)
- 혼잡 윈도우가 임계치에 도달하거나 넘어가면 혼잡 회피 실행
✔️ Reno
중복 ACK 발생 시 빠른 회복 수행