dh_0e

[Transport Layer] TCP (Transmission Control Protocol) Part II. 본문

Network Programming/Transport Layer

[Transport Layer] TCP (Transmission Control Protocol) Part II.

dh_0e 2025. 6. 3. 19:23

State Transition Diagram (상태 전이 다이어그램)

  • 일종의 설계 도면으로 TCP 상태 전이 다이어그램은 두 문자열을 슬래시(/)로 구분해 표기함
    • 첫 번째 문자열 = 입력(input): TCP가 받는 이벤트
    • 두 번째 문자열 = 출력(output): TCP가 보내는 반응

TCP State Transition Diagram

  • Part I.에서 한 부분은 검은색 실선만 따라가면 됨
  • ESTABLISHED 상태는 두 종류가 있음
    • 클라이언트용 ESTABLISHED: 일정한 순서로 요청 전송 중심
    • 서버용 ESTABLISHED: 수신 버퍼를 준비, 응답 중심
    • 흐름 제어와 오류 제어 측면에서 서로 역할이 다르므로 구분됨

 

A Common Scenario

Client States

  • Active open: 클라이언트 프로세스가 TCP에게 특정 서버 주소와 포트로 연결 요청함 (connect() 호출)
  • Active close: 클라이언트가 더 이상 보낼 데이터가 없을 때 TCP에게 연결 종료 요청을 보냄

Server States

  • Passive open: 서버 프로세스가 TCP에게 "연결을 받아들일 준비가 됐어"라고 알림 (listen() 호출)
  • 서버는 반드시 클라이언트보다 먼저 open 상태에 들어가 있어야 함
  • LISTEN 상태에 진입하여 SYN 세그먼트를 받을 때까지 유지함

Common Scenario for Connection Close

 

Denying a Connection

  • 서버가 클라이언트의 SYN 요청을 거절하는 경우
  • 클라이언트가 보낸 SYN 세그먼트의 목적지 포트 번호가 서버에서 현재 LISTEN 상태가 아닌 포트에 도착했을 때
    • 즉, 해당 포트를 열어둔 서버 application이 없다는 뜻
  • 서버는 ACK 세그먼트를 보내면서 연결을 재설정(reset)하겠다는 의미RST flag도 함께 보냄
  • 연결을 거부(denial)하며 클라이언트는 이 응답을 받고 연결 시도를 중단
  • 이후 서버는 다시 LISTEN 상태로 복귀하여 정상적인 연결 요청을 다시 받을 준비가 된 상태로 돌아감

  • UDP에선 port number 틀렸으면 ICMP 생성해서 처리
  • TCP에선 위 예시처럼 자체적으로 처리

 

TCP Send Window

  • TCP에서 송신자가 보낼 수 있는 데이터의 범위를 나타내는 window
  • Flow control: 수신자가 자신의 버퍼 상황에 따라 rwnd 값을 광고
  • Congestion control: 네트워크 상태에 따라 혼잡 윈도우(cwnd)가 조정됨
  • 송신자는 이 둘 중 더 작은 값(min{rwnd, cwnd})을 기준으로 윈도우를 설정함

단순화를 위해 100bytes짜리 윈도우를 사용함

 

TCP Recieve Window

  • TCP 수신자가 얼마나 많은 데이터를 받을 수 있는지를 나타내는 흐름 제어용 window(rwnd)
  • 송신자는 이 정보를 기반으로 보내는 데이터 양을 조절 (flow control)
  • TCP는 기본적으로 cumulative(누적) ACK를 사용함
    • 새로운 TCP 버전들은 Selective ACK(SACK)도 지원
    • 누적 ACK: 가장 마지막까지 연속으로 받은 바이트까지만 확인
    • SACK: 그 외에 중간에 받은 범위도 명시(더 정교한 재전송 가능)
      • ex) 1000-1399까지 bytes 중 1100-1199가 안 왔을 때, 누적 ACK로는 ACK=1100만 반복해서 보냄
              SACK 옵션 필드"SACK = [1200-1399]"를 추가해서 이미 받은 항목 알려줌
               >> 송신자가 불필요한 재전송 없이 빠르게 손실 패킷 회복 가능

 

Flow Control

  • 송신자와 수신자 간의 속도 균형을 맞추는 메커니즘
  • 송신자가 너무 빨리 데이터를 보내면 수신자의 버퍼가 overflow 될 수 있음
    • TCP는 수신자가 감당할 수 있는 만큼만 전송하게 제어함

  • 대부분의 TCP 구현은 Application → TCP 간 흐름 제어는 따로 없음 → TCP 내부에서만 제어
주체  역할
수신 애플리케이션 데이터를 언제 읽을지 결정함 (자유롭게 pull 방식)
수신 TCP 버퍼 상황을 보고 rwnd를 설정 → 송신 TCP에 전달
송신 TCP rwnd 값을 참고하여 데이터를 전송
송신 애플리케이션 송신 TCP에게 데이터를 넘겨줌 (제어는 TCP가 맡음)
  • 실제로는 flow control feedback이 application까지 도달하지 않고 Application(Sender)은 TCP로  데이터를 막 밀어 넣고 Application(Reciever)은 TCP로부터 필요할 때 데이터를 읽는 방식

Flow Control Example

  • 수신 윈도우의 오른쪽 벽은 왼쪽으로 후퇴하지 않음 >> 즉, 윈도우는 줄어들 수 없음
  • 송신 윈도우는 수신자가 광고하는 rwnd 값에 따라 동적으로 조정
    • 왼쪽 벽 이동(close): 새로운 ACK 수신 >> 보낸 데이터가 확인되었으므로 윈도우 시작 지점(왼쪽)이 이동함
    • 오른쪽 벽 이동(open): 수신자가 더 큰 rwnd 값을 광고 >> 보낼 수 있는 데이터 범위 증가
  • 송신 윈도우는 Shrinks(수신자의 rwnd가 작아졌을 경우 송신 윈도우의 size를 축소) 가능 
    • 예외처리기 때문에 메모리를 실제로 줄이진 않음

 

Silly Window Syndrome (SWS) by Sender

  • 송신자 측에서 발생하는 쓸데없이 작은 윈도우 문제
  • 송신 application program이 데이터를 너무 천천히 만들 때
    • TCP는 특별한 제약이 없으면 그대로 1byte 세그먼트를 만들어 전송
    • 헤더는 20bytes인데, 데이터는 1byte >> 매우 비효율적
  • 네트워크의 비효율을 초래하는 현상

해결책

Nagle's Algorithhm (for sender)

  1. 첫 데이터 전송
    • 송신 TCP는 처음 받은 데이터를 즉시 전송 (설령 1byte라도 즉시 세그먼트 생성 + 전송) 
  2. 그 다음부터는 대기
    • 그 이후에는 송신 TCP가 두 조건 중 하나를 만족할 때까지 기다림:
      1. 이전 전송에 대한 ACK를 수신
      2. 버퍼에 MSS(최대 세그먼트 크기)만큼 데이터가 누적됨
  3. 위 조건 중 하나 만족 >> 세그먼트 전송, 이후에도 2 규칙을 반복 적용 
  • long distance에 유리하지만 지연에 민감한 서비스에는 비효율적일 수 있음
    • ex) RTT(Round Trip Time)가 매우 짧은 경우: ACK가 너무 빨리 와서 누적 없이 자주 전송됨
    • ex2) 실시간 응답 앱(게임, 채팅 등): 유저 입력에 즉각 반응해야 해서 대기 자체가 문제 됨

 

Silly Window Syndrome (SWS) by Reciever

  • 수신자 측에서 발생하는 쓸데없이 작은 윈도우 문제
  • 수신 application program이 데이터를 너무 늦게 읽음
    • ex)
    • 수신 TCP의 버퍼가 4KB이고, 송신자는 4KB 데이터를 전송
    • 수신 버퍼가 가득 참 >> rwnd=0 광고 >> make sender stop
    • 수신 애플리케이션이 1byte만 읽음 >> rwnd=1로 업데이트
    • 송신자는 1byte만 보낼 수 있음 = 비효율적

해결책

Clark's Solution

  • ACK 즉시 전송: 데이터가 도착하면 바로 ACK 전송
  • 윈도우 0 광고: 수신 버퍼가 꽉 찼으면 rwnd=0으로 설정 >> make sender stop
  • 충분한 공간 생기기 전까지 윈도우 재개 광고 안 함: 버퍼에 MSS 이상 공간 생길 때까지 기다림
  • 즉, 지연 없이 확인은 해주지만 송신자가 자잘한 세그먼트를 보내지 않도록 rwnd=0으로 막았다가
    버퍼가 한 번에 충분한 양(ex: 1KB)을 받을 수 있다면 데이터 전송을 재기시키는 것 

Delayed Acknowledgment

  • 수신 TCP는 버퍼가 어느 정도 비워질 때까지(App이 처리해서 ACK 보낼게 많아질 때까지) ACK를 지연
    • 200ms~500ms 정도 지연시켜서 ACK를 한꺼번에 전송
    • ACK 보내는 횟수가 줄어들면 제어 패킷 감소 >> 네트워크 효율 증가
  • 한꺼번에 많은 데이터를 수신하고 처리 후 ACK 전송 >> 효율 증가
    • rwnd로 limit을 안 걸어주기 때문에 Sender가 많은 양의 데이터를 재전송할 수 있음
  • 즉, 여러 세그먼트를 하나의 ACK로 처리함으로써 패킷 수를 줄이고, 네트워크 오버헤드를 줄여 전체 효율을 높이는 전략

 

Error Control

  • 손실되거나 망가진 세그먼트 탐색 및 재전송, 순서대로 오지 않은 세그먼트 확인, 중복 세그먼트 탐색 및 삭제
  • TCP가 신뢰성을 보장하기 위해 사용하는 3가지 핵심 도구 
    1. Checksum
      • 각 TCP 세그먼트에는 체크섬 필드(16bits)가 포함됨
      • 송신 시 전체 데이터 값을 계산해 놓고, 수신 시 다시 계산하여 패킷 손상 여부 검출
        • 패킷 손상 시 세그먼트 폐기 & ACK 보내지 않음
    2. Acknowledgment(ACK)
      • 수신자가 잘 받은 데이터 범위를 송신자에게 알려줌(영수증 개념)
      • 기본적으로 누적 ACK 사용, option 활성화해서 SACK 곁들일 수 있음
    3. Fast Retransmission / Time-out(타임아웃 재전송)
      • ACK가 안 온다고 타이머가 만료될 때까지 기다리지 않고,
        중복된 ACK가 3개 이상(Origin ACK 포함 4개 이상) 도착하면 즉시 재전송

Fast Retransmission Example I
Fast Retransmission Example II

Generating Acknowledgments (생성 규칙)

  1. Piggyback Acknowledgment (데이터 전송 시 ACK 포함)
    • A가 B에게 데이터 세그먼트를 보낼 때, 가능하면 ACK도 함께 포함시킴(piggyback)
  2. Delayed ACK (지연 응답)
    • 1) 수신자가 보낼 데이터가 없고
      2) 기대한 시퀀스 번호의 in-order segment를 받은 상태고
      3) 이전 segment가 이미 ACK 됐을 경우
    • ACK 전송을 일정 시간(보통 500ms) 지연
    • SWS 해결책 Delayed ACK 알고리즘 그대로
  3. 즉시 ACK 전송 조건
    • 수신자가 기대한 시퀀스 번호를 받았지만, 이전 세그먼트가 아직 ACK 되지 않은 경우(Delayed 되고 있는 경우)
    • 바로 ACK 전송하거나 (usually)
      세그먼트 2개까지만 허용해서 ACK 안 된 상태로 2개 연속 존재하지 않게끔 함
    • ex) 세그먼트 S1에 대하여 Delayed ACK가 500ms 지연 도중
            새로운 세그먼트 S2가 들어와도 반응 없음(아직 ACK 안 된 세그먼트 2개)
            새로운 세그먼트 S3가 도착하면 이제 3개 연속으로 ACK 안 된 상태가 되므로 즉시 ACK 전송
    • Rule 1, 2, 3 Example
  4. Out-of-order 세그먼트가 도착한 경우
    • 수신자가 기대한 시퀀스 번호보다 큰 번호의 세그먼트를 받은 경우
    • 수신자는 그 세그먼트를 버리지 않고 저장할 수 있지만
      우선 ACK를 즉시 전송해서 송신자에게 "아직 중간 게 안 왔어, 기대하는 건 이 번호야"를 알려줌
  5. Missing segment가 도착한 경우
    • 이 전에 손실되었던 세그먼트가 지연되어 도착한 상황
    • 수신자는 해당 세그먼트를 포함한 누적 ACK를 즉시 전송
  6. Duplicate segment가 도착한 경우
    • 이미 받은 세그먼트를 또 받은 상황
    • 수신자는 해당 세그먼트를 discard하면서 즉시 ACK 전송(시퀀스 번호 이거라고)

Rule 3, 4, 5 Example
RTO가 아직 안 끝났는데...? 아마 내부 로직상 Resending한 건가

Out-of-Order Segments

  • 현대 TCP는 예전의 단순한 TCP 구현과 달리 순서가 어긋난 세그먼트도 버리지 않고, 버퍼에 보관
  • Application에게 직접 전달되지는 않음
  • TCP는 바이트 스트림의 순서를 보장하는 프로토콜이기 때문에 application은 항상 올바른 순서로만 데이터 수신

Lost acknowledgment 

Cumulative ACK Example