일련번호와 확인 응답 번호의 구조

일련번호와 확인 응답 번호의 구조

일련번호와 확인 응답 번호의 구조

1. 일련번호와 확인 응답 번호란?

개념

┌─────────────────────────────────────────────────────────────┐
│              일련번호와 확인 응답 번호                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  3-Way Handshake 완료 후, 실제 데이터를 주고받을 때         │
│  TCP 헤더의 두 가지 번호가 핵심 역할을 한다:                │
│                                                             │
│  1. 일련번호 (Sequence Number)                              │
│  ─────────────────────────────────────────                  │
│     • 송신측이 "이 데이터가 몇 번째인지" 알려줌             │
│     • 데이터의 순서를 표시                                   │
│     • 32비트 (약 42억까지 표현 가능)                        │
│                                                             │
│  2. 확인 응답 번호 (Acknowledgment Number)                  │
│  ─────────────────────────────────────────                  │
│     • 수신측이 "여기까지 받았으니 다음 거 보내줘" 알려줌    │
│     • 다음에 받기 원하는 데이터 번호                        │
│     • ACK 플래그가 1일 때만 유효                            │
│                                                             │
│                                                             │
│  왜 필요한가?                                               │
│  ─────────────────────────────────────────                  │
│  • TCP는 대용량 데이터를 분할해서 전송                      │
│  • 네트워크에서 패킷 순서가 뒤바뀔 수 있음                  │
│  • 패킷이 손실될 수 있음                                    │
│  → 번호로 순서 보장 + 손실 감지 + 재전송                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

TCP 헤더에서의 위치

┌─────────────────────────────────────────────────────────────┐
│                     TCP 헤더 구조                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│    0                   16                  31               │
│    ├────────────────────┼────────────────────┤              │
│    │   출발지 포트       │   목적지 포트       │              │
│    │   (16비트)         │   (16비트)         │              │
│    ├────────────────────┴────────────────────┤              │
│    │  ┌─────────────────────────────────────┐│              │
│    │  │     일련번호 (Sequence Number)      ││ ← 여기!     │
│    │  │           (32비트)                  ││              │
│    │  └─────────────────────────────────────┘│              │
│    ├─────────────────────────────────────────┤              │
│    │  ┌─────────────────────────────────────┐│              │
│    │  │   확인 응답 번호 (ACK Number)       ││ ← 여기!     │
│    │  │           (32비트)                  ││              │
│    │  └─────────────────────────────────────┘│              │
│    ├────────┬──────┬────┬────────────────────┤              │
│    │헤더길이│예약  │플래그│    윈도우 크기     │              │
│    │ (4bit)│(6bit)│(6bit)│    (16비트)       │              │
│    ├────────┴──────┴────┴────────────────────┤              │
│    │   체크섬      │    긴급 포인터           │              │
│    └────────────────┴────────────────────────┘              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

2. 일련번호 (Sequence Number) 상세

일련번호의 역할

┌─────────────────────────────────────────────────────────────┐
│                    일련번호 (Sequence Number)                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  정의:                                                      │
│  • 전송하는 데이터의 첫 번째 바이트 번호                    │
│  • "이 세그먼트는 N번째 바이트부터 시작해요"                │
│                                                             │
│                                                             │
│  초기 일련번호 (ISN: Initial Sequence Number)               │
│  ─────────────────────────────────────────                  │
│  • 연결 시작 시 랜덤하게 선택                               │
│  • 0부터 시작하지 않음 (보안상 이유)                        │
│  • 3-Way Handshake에서 서로 교환                            │
│                                                             │
│                                                             │
│  예시:                                                      │
│  ─────────────────────────────────────────                  │
│                                                             │
│  원본 데이터: "Hello, World!" (13바이트)                    │
│                                                             │
│  ISN = 1000 이라면:                                         │
│                                                             │
│  ┌─────────────────────────────────────────────────┐        │
│  │ 바이트 위치:  1000 1001 1002 1003 1004 ...      │        │
│  │ 데이터:       H    e    l    l    o   ...       │        │
│  └─────────────────────────────────────────────────┘        │
│                                                             │
│  Seq=1000 → "H"부터 시작하는 데이터                         │
│  Seq=1005 → ", "부터 시작하는 데이터                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

일련번호 증가 규칙

┌─────────────────────────────────────────────────────────────┐
│                    일련번호 계산 규칙                        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  다음 Seq = 현재 Seq + 전송한 데이터 바이트 수              │
│                                                             │
│                                                             │
│  예시: 1000바이트씩 3번 전송                                │
│  ─────────────────────────────────────────                  │
│                                                             │
│  전송 1: Seq = 1000, 데이터 = 1000바이트                    │
│          → 바이트 1000 ~ 1999 전송                          │
│                                                             │
│  전송 2: Seq = 2000, 데이터 = 1000바이트                    │
│          → 바이트 2000 ~ 2999 전송                          │
│                                                             │
│  전송 3: Seq = 3000, 데이터 = 1000바이트                    │
│          → 바이트 3000 ~ 3999 전송                          │
│                                                             │
│                                                             │
│  ┌──────────────────────────────────────────────────────┐   │
│  │    Seq=1000      Seq=2000      Seq=3000              │   │
│  │    ┌────────┐    ┌────────┐    ┌────────┐           │   │
│  │    │ 1000B  │    │ 1000B  │    │ 1000B  │           │   │
│  │    │데이터 1│    │데이터 2│    │데이터 3│           │   │
│  │    └────────┘    └────────┘    └────────┘           │   │
│  │    1000-1999     2000-2999     3000-3999            │   │
│  └──────────────────────────────────────────────────────┘   │
│                                                             │
│                                                             │
│  특별한 경우:                                               │
│  ─────────────────────────────────────────                  │
│  • SYN 패킷: Seq 1 소비 (데이터 없어도)                     │
│  • FIN 패킷: Seq 1 소비 (데이터 없어도)                     │
│  • ACK만 있는 패킷: Seq 소비 안 함                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

3. 확인 응답 번호 (Acknowledgment Number) 상세

확인 응답 번호의 역할

┌─────────────────────────────────────────────────────────────┐
│              확인 응답 번호 (Acknowledgment Number)          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  정의:                                                      │
│  • 수신측이 다음에 받기 원하는 바이트 번호                  │
│  • "N번까지 잘 받았으니, N+1번부터 보내줘"                  │
│                                                             │
│                                                             │
│  계산 공식:                                                 │
│  ─────────────────────────────────────────                  │
│                                                             │
│  ACK Number = 받은 Seq + 받은 데이터 크기                   │
│                                                             │
│                                                             │
│  예시:                                                      │
│  ─────────────────────────────────────────                  │
│                                                             │
│  송신측: Seq=1000, 데이터=500바이트 전송                    │
│          → 바이트 1000 ~ 1499 전송                          │
│                                                             │
│  수신측: ACK=1500 응답                                      │
│          → "1500번부터 보내줘" (1000~1499는 잘 받았어)      │
│                                                             │
│                                                             │
│  [송신측]                           [수신측]                │
│      │                                  │                   │
│      │    Seq=1000, Len=500             │                   │
│      ├─────────────────────────────────→│                   │
│      │    (바이트 1000~1499)            │                   │
│      │                                  │                   │
│      │             ACK=1500             │                   │
│      │←─────────────────────────────────┤                   │
│      │    "1500번부터 보내줘!"          │                   │
│      │                                  │                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

누적 확인 응답 (Cumulative ACK)

┌─────────────────────────────────────────────────────────────┐
│                   누적 확인 응답                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  TCP는 "누적 ACK" 방식 사용                                 │
│  → ACK=N은 "N-1번까지 모두 받았다"는 의미                   │
│                                                             │
│                                                             │
│  예시: 3개 세그먼트 연속 전송                               │
│  ─────────────────────────────────────────                  │
│                                                             │
│  [송신측]                              [수신측]             │
│      │                                     │                │
│      │    Seq=1000, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │    Seq=1100, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │    Seq=1200, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │              ACK=1300               │                │
│      │←────────────────────────────────────┤                │
│      │   "1300번까지 모두 받았어!"         │                │
│      │   (1000~1299 바이트 확인)           │                │
│      │                                     │                │
│                                                             │
│                                                             │
│  장점:                                                      │
│  • 모든 패킷마다 ACK 안 보내도 됨 → 효율적                 │
│  • 하나의 ACK로 여러 세그먼트 확인 가능                     │
│                                                             │
└─────────────────────────────────────────────────────────────┘

4. 데이터 전송 과정 예시

전체 통신 흐름

┌─────────────────────────────────────────────────────────────┐
│                    데이터 전송 전체 과정                     │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [클라이언트]                              [서버]           │
│                                                             │
│  ═══════════ 1단계: 연결 설정 (3-Way Handshake) ═══════════ │
│      │                                        │             │
│      │    SYN, Seq=100                        │             │
│      ├───────────────────────────────────────→│             │
│      │                                        │             │
│      │    SYN+ACK, Seq=300, Ack=101           │             │
│      │←───────────────────────────────────────┤             │
│      │                                        │             │
│      │    ACK, Seq=101, Ack=301               │             │
│      ├───────────────────────────────────────→│             │
│      │                                        │             │
│  ═══════════ 2단계: 데이터 전송 ═══════════════════════════ │
│      │                                        │             │
│      │    Seq=101, Len=200 (데이터: GET ...)  │             │
│      ├───────────────────────────────────────→│             │
│      │    "101~300번 바이트 보내요"           │             │
│      │                                        │             │
│      │              ACK=301                   │             │
│      │←───────────────────────────────────────┤             │
│      │    "301번부터 보내줘"                  │             │
│      │                                        │             │
│      │    Seq=301, Len=1000 (HTML 데이터)     │             │
│      │←───────────────────────────────────────┤             │
│      │    "301~1300번 바이트 보내요"          │             │
│      │                                        │             │
│      │              ACK=1301                  │             │
│      ├───────────────────────────────────────→│             │
│      │    "1301번부터 보내줘"                 │             │
│      │                                        │             │
│  ═══════════ 3단계: 연결 종료 (4-Way Handshake) ═══════════ │
│      │                                        │             │
│      │    FIN, Seq=301, Ack=1301              │             │
│      ├───────────────────────────────────────→│             │
│      │                                        │             │
│      │    ACK=302                             │             │
│      │←───────────────────────────────────────┤             │
│      │                                        │             │
│      │    FIN, Seq=1301, Ack=302              │             │
│      │←───────────────────────────────────────┤             │
│      │                                        │             │
│      │    ACK=1302                            │             │
│      ├───────────────────────────────────────→│             │
│      │                                        │             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Seq/Ack 번호 추적 예시

상세 번호 추적:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

초기 상태:
• 클라이언트 ISN: 100
• 서버 ISN: 300

┌─────────────────────────────────────────────────────────────┐
│  단계   │   패킷 내용              │  Seq/Ack 계산         │
├─────────┼──────────────────────────┼───────────────────────┤
│    1    │ C→S: SYN                 │ Seq=100               │
│         │                          │ (SYN은 Seq 1 소비)    │
├─────────┼──────────────────────────┼───────────────────────┤
│    2    │ S→C: SYN+ACK             │ Seq=300, Ack=101      │
│         │                          │ (Ack=100+1)           │
├─────────┼──────────────────────────┼───────────────────────┤
│    3    │ C→S: ACK                 │ Seq=101, Ack=301      │
│         │                          │ (Ack=300+1)           │
├─────────┼──────────────────────────┼───────────────────────┤
│    4    │ C→S: 데이터 200B         │ Seq=101, Len=200      │
│         │                          │ 다음 Seq=101+200=301  │
├─────────┼──────────────────────────┼───────────────────────┤
│    5    │ S→C: ACK                 │ Ack=301               │
│         │                          │ (101+200=301)         │
├─────────┼──────────────────────────┼───────────────────────┤
│    6    │ S→C: 데이터 1000B        │ Seq=301, Len=1000     │
│         │                          │ 다음 Seq=301+1000=1301│
├─────────┼──────────────────────────┼───────────────────────┤
│    7    │ C→S: ACK                 │ Ack=1301              │
│         │                          │ (301+1000=1301)       │
└─────────┴──────────────────────────┴───────────────────────┘

5. 재전송 제어

재전송이 필요한 경우

┌─────────────────────────────────────────────────────────────┐
│                      재전송 제어                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  정의:                                                      │
│  • 데이터가 손상되거나 유실된 경우 다시 보내는 것           │
│  • TCP의 신뢰성 보장 핵심 메커니즘                          │
│                                                             │
│                                                             │
│  재전송이 필요한 상황:                                      │
│  ─────────────────────────────────────────                  │
│                                                             │
│  1. 패킷 손실 (Packet Loss)                                 │
│     • 네트워크 혼잡으로 라우터가 패킷 버림                  │
│     • 물리적 연결 문제                                      │
│                                                             │
│  2. 패킷 손상 (Packet Corruption)                           │
│     • 체크섬 검증 실패                                      │
│     • 수신측이 패킷 폐기                                    │
│                                                             │
│  3. ACK 손실                                                │
│     • 수신측은 받았지만 ACK가 손실됨                        │
│     • 송신측은 ACK 못 받음 → 재전송                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

타임아웃 재전송 (RTO)

┌─────────────────────────────────────────────────────────────┐
│              타임아웃 재전송 (Retransmission Timeout)        │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  원리:                                                      │
│  • 데이터 전송 후 타이머 시작                               │
│  • 타임아웃 내에 ACK 없으면 재전송                          │
│                                                             │
│                                                             │
│  [송신측]                              [수신측]             │
│      │                                     │                │
│      │    Seq=1000, Len=100                │                │
│      ├─────────────────────╳               │  패킷 손실!    │
│      │                                     │                │
│      │    ← 타이머 시작 →                  │                │
│      │                                     │                │
│      │    ... 시간 경과 ...                │                │
│      │                                     │                │
│      │    ⏰ 타임아웃!                     │                │
│      │                                     │                │
│      │    Seq=1000, Len=100 (재전송)       │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │              ACK=1100               │                │
│      │←────────────────────────────────────┤                │
│      │                                     │                │
│                                                             │
│                                                             │
│  RTO (Retransmission Timeout) 계산:                         │
│  ─────────────────────────────────────────                  │
│  • RTT (Round Trip Time) 기반으로 동적 계산                 │
│  • RTO = SRTT + 4 × RTTVAR                                 │
│    - SRTT: Smoothed RTT (평균 RTT)                         │
│    - RTTVAR: RTT 변동폭                                    │
│  • 재전송 실패 시 RTO 2배로 증가 (지수 백오프)             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

빠른 재전송 (Fast Retransmit)

┌─────────────────────────────────────────────────────────────┐
│                    빠른 재전송 (Fast Retransmit)            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  원리:                                                      │
│  • 중복 ACK 3개 받으면 타임아웃 기다리지 않고 즉시 재전송   │
│  • 더 빠른 복구 가능                                        │
│                                                             │
│                                                             │
│  [송신측]                              [수신측]             │
│      │                                     │                │
│      │    Seq=1000, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │    Seq=1100, Len=100                │                │
│      ├─────────────────────╳               │  손실!        │
│      │                                     │                │
│      │    Seq=1200, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │  (순서 아님)   │
│      │              ACK=1100               │  ← 중복 ACK 1  │
│      │←────────────────────────────────────┤                │
│      │                                     │                │
│      │    Seq=1300, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │              ACK=1100               │  ← 중복 ACK 2  │
│      │←────────────────────────────────────┤                │
│      │                                     │                │
│      │    Seq=1400, Len=100                │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │              ACK=1100               │  ← 중복 ACK 3  │
│      │←────────────────────────────────────┤                │
│      │                                     │                │
│      │  ┌────────────────────────────┐     │                │
│      │  │ 중복 ACK 3개! 즉시 재전송! │     │                │
│      │  └────────────────────────────┘     │                │
│      │                                     │                │
│      │    Seq=1100, Len=100 (재전송)       │                │
│      ├────────────────────────────────────→│  ✓ 받음       │
│      │                                     │                │
│      │              ACK=1500               │                │
│      │←────────────────────────────────────┤                │
│      │    "1500번까지 다 받았어!"          │                │
│      │    (버퍼에 쌓인 것도 한 번에 확인)  │                │
│      │                                     │                │
│                                                             │
│                                                             │
│  왜 3개인가?                                                │
│  ─────────────────────────────────────────                  │
│  • 1~2개: 단순 순서 뒤바뀜일 수 있음 (손실 아님)           │
│  • 3개: 높은 확률로 실제 손실 발생                         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

6. 윈도우 크기 (Window Size)

윈도우 크기란?

┌─────────────────────────────────────────────────────────────┐
│                    윈도우 크기 (Window Size)                 │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  정의:                                                      │
│  • 수신측이 한 번에 받을 수 있는 데이터 크기 (바이트)       │
│  • TCP 헤더의 16비트 필드                                   │
│  • 최대 65,535 바이트 (옵션으로 확장 가능)                  │
│                                                             │
│                                                             │
│  목적:                                                      │
│  ─────────────────────────────────────────                  │
│  • 흐름 제어 (Flow Control)                                 │
│  • 수신측 버퍼 오버플로우 방지                              │
│  • 송수신 속도 조절                                         │
│                                                             │
│                                                             │
│  비유:                                                      │
│  ─────────────────────────────────────────                  │
│                                                             │
│  수신측 = 물탱크, 윈도우 크기 = 탱크 여유 공간              │
│                                                             │
│  ┌─────────────┐                                            │
│  │  ▓▓▓▓▓▓▓▓   │ ← 이미 받은 데이터 (처리 대기 중)        │
│  │  ▓▓▓▓▓▓▓▓   │                                           │
│  │             │ ← 윈도우 크기 (더 받을 수 있는 공간)      │
│  │             │                                           │
│  └─────────────┘                                            │
│                                                             │
│  탱크가 가득 차면 → 윈도우 크기 = 0 → "잠깐 멈춰!"        │
│  탱크가 비면 → 윈도우 크기 증가 → "더 보내도 돼!"         │
│                                                             │
└─────────────────────────────────────────────────────────────┘

버퍼와 오버플로우

┌─────────────────────────────────────────────────────────────┐
│                   버퍼와 오버플로우                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  버퍼 (Buffer):                                             │
│  • 수신한 세그먼트를 임시 저장하는 메모리 공간              │
│  • 애플리케이션이 데이터를 가져갈 때까지 보관               │
│                                                             │
│                                                             │
│  오버플로우 (Overflow):                                     │
│  • 데이터가 버퍼 용량을 초과하는 현상                       │
│  • 새로운 데이터를 받을 수 없음 → 패킷 폐기                │
│                                                             │
│                                                             │
│  정상 상태:                                                 │
│  ─────────────────────────────────────────                  │
│                                                             │
│  ┌─────────────────────────────────────┐                    │
│  │  수신 버퍼 (4096 바이트)            │                    │
│  ├─────────────────────────────────────┤                    │
│  │  ▓▓▓▓▓▓▓▓▓▓│                       │                    │
│  │  사용 중    │    여유 공간         │                    │
│  │  (1000B)    │    (3096B)           │                    │
│  │             │   = 윈도우 크기      │                    │
│  └─────────────────────────────────────┘                    │
│                                                             │
│                                                             │
│  오버플로우 위험:                                           │
│  ─────────────────────────────────────────                  │
│                                                             │
│  ┌─────────────────────────────────────┐                    │
│  │  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│ ← 거의 가득!      │
│  │  사용 중 (4000B)        │ 여유 96B │                    │
│  └─────────────────────────────────────┘                    │
│                                                             │
│  → 윈도우 크기 = 96 광고 → 송신측은 96바이트만 전송       │
│                                                             │
│                                                             │
│  오버플로우 발생:                                           │
│  ─────────────────────────────────────────                  │
│                                                             │
│  ┌─────────────────────────────────────┐  ┌───┐            │
│  │  ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│  │ ✗ │ ← 폐기!   │
│  │  가득 참! (4096B)                   │  └───┘            │
│  └─────────────────────────────────────┘    새 패킷        │
│                                                             │
│  → 윈도우 크기 = 0 광고 → 송신측 전송 중단                 │
│                                                             │
└─────────────────────────────────────────────────────────────┘

윈도우 크기 조절 과정

┌─────────────────────────────────────────────────────────────┐
│                   윈도우 크기 조절 흐름                      │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  [송신측]                              [수신측]             │
│                                        버퍼: 4096B          │
│      │                                     │                │
│      │  ── 3-Way Handshake ──              │                │
│      │       Window=4096                   │                │
│      │←────────────────────────────────────┤  "4096B 가능"  │
│      │                                     │                │
│      │    1000B 전송                       │                │
│      ├────────────────────────────────────→│  사용: 1000B   │
│      │                                     │                │
│      │    1000B 전송                       │                │
│      ├────────────────────────────────────→│  사용: 2000B   │
│      │                                     │                │
│      │       ACK, Window=2096              │                │
│      │←────────────────────────────────────┤  "2096B 가능"  │
│      │                                     │                │
│      │    1000B 전송                       │                │
│      ├────────────────────────────────────→│  사용: 3000B   │
│      │                                     │                │
│      │    1000B 전송                       │                │
│      ├────────────────────────────────────→│  사용: 4000B   │
│      │                                     │                │
│      │       ACK, Window=96                │                │
│      │←────────────────────────────────────┤  "96B만 가능!" │
│      │                                     │                │
│      │    96B만 전송                       │                │
│      ├────────────────────────────────────→│  사용: 4096B   │
│      │                                     │                │
│      │       ACK, Window=0                 │  가득 참!      │
│      │←────────────────────────────────────┤  "잠깐 멈춰!"  │
│      │                                     │                │
│      │  ═══════ 전송 중단 ═══════         │                │
│      │                                     │                │
│      │     (애플리케이션이 데이터 처리)    │  처리 중...    │
│      │                                     │                │
│      │     Window Update, Window=2000      │                │
│      │←────────────────────────────────────┤  "2000B 비었어"│
│      │                                     │                │
│      │  ═══════ 전송 재개 ═══════         │                │
│      │                                     │                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

슬라이딩 윈도우 (Sliding Window)

┌─────────────────────────────────────────────────────────────┐
│                    슬라이딩 윈도우                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  정의:                                                      │
│  • ACK를 받을 때마다 윈도우가 "슬라이딩"하는 방식           │
│  • ACK 기다리지 않고 여러 세그먼트 연속 전송 가능          │
│  • 네트워크 효율성 극대화                                   │
│                                                             │
│                                                             │
│  송신측 버퍼 상태:                                          │
│  ─────────────────────────────────────────                  │
│                                                             │
│  초기 상태 (윈도우 크기 = 4):                               │
│  ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐                          │
│  │1 │2 │3 │4 │5 │6 │7 │8 │9 │10│                          │
│  └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘                          │
│   ├────────────┤                                            │
│   └─ 전송 가능 ─┘                                           │
│                                                             │
│                                                             │
│  1~2 전송 후:                                               │
│  ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐                          │
│  │● │● │3 │4 │5 │6 │7 │8 │9 │10│                          │
│  └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘                          │
│   │전송됨 │← 전송 가능 →│                                   │
│    ACK대기                                                  │
│                                                             │
│                                                             │
│  ACK(3) 수신 → 윈도우 슬라이딩:                             │
│  ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐                          │
│  │✓ │✓ │● │● │5 │6 │7 │8 │9 │10│                          │
│  └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘                          │
│  ACK됨   │전송됨│← 전송 가능 →│                             │
│           ACK대기                                           │
│                                                             │
│           ↓ 윈도우가 오른쪽으로 슬라이딩!                   │
│                                                             │
│                                                             │
│  비효율적 방식 (Stop-and-Wait):                             │
│  ─────────────────────────────────────────                  │
│  송신 → ACK대기 → ACK수신 → 송신 → ACK대기 → ...           │
│  • 한 번에 하나씩만 전송                                    │
│  • 네트워크 유휴 시간 많음                                  │
│                                                             │
│                                                             │
│  효율적 방식 (슬라이딩 윈도우):                             │
│  ─────────────────────────────────────────                  │
│  송신1 → 송신2 → 송신3 → 송신4 → ACK(1-2) → 송신5 → ...   │
│  • 윈도우 크기만큼 연속 전송                                │
│  • 파이프라인 효과                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

윈도우 크기 확장 (Window Scaling)

┌─────────────────────────────────────────────────────────────┐
│                   윈도우 스케일링                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  문제:                                                      │
│  • TCP 헤더의 윈도우 크기는 16비트                          │
│  • 최대 65,535 바이트 (64KB)                                │
│  • 고속 네트워크에서는 너무 작음!                           │
│                                                             │
│                                                             │
│  해결: Window Scale 옵션 (RFC 1323)                         │
│  ─────────────────────────────────────────                  │
│  • 3-Way Handshake 시 협상                                  │
│  • 윈도우 크기에 2^n 을 곱함                                │
│  • 최대 스케일 팩터: 14 (2^14 = 16,384배)                   │
│                                                             │
│                                                             │
│  실제 윈도우 크기 = 헤더의 윈도우 값 × 2^(스케일 팩터)     │
│                                                             │
│                                                             │
│  예시:                                                      │
│  ─────────────────────────────────────────                  │
│                                                             │
│  스케일 팩터 = 7                                            │
│  헤더의 윈도우 = 8192                                       │
│                                                             │
│  실제 윈도우 = 8192 × 2^7                                   │
│              = 8192 × 128                                   │
│              = 1,048,576 바이트 (1MB)                       │
│                                                             │
│                                                             │
│  최대 윈도우 크기:                                          │
│  65,535 × 2^14 = 1,073,725,440 바이트 (약 1GB)             │
│                                                             │
│                                                             │
│  협상 과정:                                                 │
│  ─────────────────────────────────────────                  │
│                                                             │
│  [클라이언트]                         [서버]                │
│       │                                  │                  │
│       │  SYN, Window=65535               │                  │
│       │  Option: Window Scale=7          │                  │
│       ├─────────────────────────────────→│                  │
│       │                                  │                  │
│       │  SYN+ACK, Window=65535           │                  │
│       │  Option: Window Scale=8          │                  │
│       │←─────────────────────────────────┤                  │
│       │                                  │                  │
│       │  ACK                             │                  │
│       ├─────────────────────────────────→│                  │
│       │                                  │                  │
│       │  (이후 통신에서 스케일 팩터 적용)│                  │
│       │                                  │                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

7. 실무 활용

Wireshark로 Seq/Ack 분석

Wireshark에서 Seq/Ack 번호 확인:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

No.  Time    Source      Dest        Info
1    0.000   Client      Server      [SYN] Seq=0
2    0.015   Server      Client      [SYN, ACK] Seq=0 Ack=1
3    0.015   Client      Server      [ACK] Seq=1 Ack=1
4    0.016   Client      Server      [PSH, ACK] Seq=1 Ack=1 Len=200
5    0.025   Server      Client      [ACK] Seq=1 Ack=201
6    0.030   Server      Client      [PSH, ACK] Seq=1 Ack=201 Len=1500
7    0.031   Client      Server      [ACK] Seq=201 Ack=1501


패킷 4번 상세:
┌───────────────────────────────────────────────────────────┐
│  Transmission Control Protocol                             │
│  ├─ Source Port: 52341                                    │
│  ├─ Destination Port: 80                                  │
│  ├─ Sequence Number: 1 (relative)                         │
│  ├─ Acknowledgment Number: 1 (relative)                   │
│  ├─ Header Length: 20 bytes                               │
│  ├─ Flags: 0x018 (PSH, ACK)                               │
│  ├─ Window: 65535                                         │
│  ├─ TCP Segment Len: 200                                  │
│  └─ [Next Seq: 201]  ← Wireshark가 계산해줌              │
└───────────────────────────────────────────────────────────┘


유용한 Wireshark 필터:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

# 특정 Seq 번호
tcp.seq == 1000

# 특정 ACK 번호
tcp.ack == 2000

# 재전송 패킷
tcp.analysis.retransmission

# 중복 ACK
tcp.analysis.duplicate_ack

# 순서 어긋난 패킷
tcp.analysis.out_of_order

# 윈도우 크기 0
tcp.window_size == 0

# 윈도우 업데이트
tcp.analysis.window_update

netstat으로 윈도우 크기 확인

Windows:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

> netstat -an

활성 연결

  프로토콜  로컬 주소           외부 주소              상태
  TCP       192.168.1.10:52341  142.250.185.78:443     ESTABLISHED


상세 정보 (관리자):

> netsh interface tcp show global

TCP 전역 매개 변수
----------------------------------------------
수신측 창 자동 조정 수준   : normal
추가 기능 창 휴리스틱      : disabled
ECN 기능                   : disabled
타임스탬프                  : disabled


Linux:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

$ ss -ti

State    Recv-Q   Send-Q   Local:Port   Peer:Port
ESTAB    0        0        192.168.1.10:52341  142.250.185.78:443
         cubic wscale:7,7 rto:204 rtt:15.2/7.6 ato:40 mss:1448
         pmtu:1500 rcvmss:1448 advmss:1448 cwnd:10 bytes_sent:1234
         bytes_received:5678 segs_out:20 segs_in:15
         data_segs_out:10 data_segs_in:8 send 7.6Mbps
         lastsnd:1234 lastrcv:1234 lastack:1234 pacing_rate 15.2Mbps
         delivery_rate 7.6Mbps app_limited busy:1234ms
         rcv_rtt:15 rcv_space:14600 rcv_ssthresh:64088
         minrtt:15


주요 지표:
• wscale:7,7     - 윈도우 스케일 팩터 (송신:7, 수신:7)
• cwnd:10       - 혼잡 윈도우 (10 세그먼트)
• rcv_space    - 수신 버퍼 크기
• rto:204      - 재전송 타임아웃 (204ms)
• rtt:15.2     - Round Trip Time (15.2ms)

성능 튜닝 팁

┌─────────────────────────────────────────────────────────────┐
│                   TCP 성능 튜닝                             │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 버퍼 크기 조정 (Linux)                                  │
│  ─────────────────────────────────────────                  │
│                                                             │
│  # 현재 설정 확인                                           │
│  $ sysctl net.core.rmem_max                                │
│  $ sysctl net.core.wmem_max                                │
│  $ sysctl net.ipv4.tcp_rmem                                │
│  $ sysctl net.ipv4.tcp_wmem                                │
│                                                             │
│  # 수신 버퍼 최대값 증가 (예: 16MB)                        │
│  $ sysctl -w net.core.rmem_max=16777216                    │
│                                                             │
│  # 송신 버퍼 최대값 증가 (예: 16MB)                        │
│  $ sysctl -w net.core.wmem_max=16777216                    │
│                                                             │
│  # TCP 버퍼 자동 조정 (min, default, max)                  │
│  $ sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216"       │
│  $ sysctl -w net.ipv4.tcp_wmem="4096 65536 16777216"       │
│                                                             │
│                                                             │
│  2. 윈도우 스케일링 활성화                                  │
│  ─────────────────────────────────────────                  │
│                                                             │
│  $ sysctl -w net.ipv4.tcp_window_scaling=1                 │
│                                                             │
│                                                             │
│  3. 적절한 BDP 계산                                         │
│  ─────────────────────────────────────────                  │
│                                                             │
│  BDP (Bandwidth-Delay Product):                            │
│  = 대역폭 × RTT                                            │
│                                                             │
│  예: 1Gbps 링크, RTT=100ms                                 │
│  BDP = 1,000,000,000 bps × 0.1s                            │
│      = 100,000,000 bits                                    │
│      = 12,500,000 bytes (약 12MB)                          │
│                                                             │
│  → 버퍼 크기를 BDP 이상으로 설정해야 최대 성능             │
│                                                             │
│                                                             │
│  4. Windows에서 조정                                        │
│  ─────────────────────────────────────────                  │
│                                                             │
│  # 자동 튜닝 활성화                                         │
│  > netsh interface tcp set global autotuninglevel=normal   │
│                                                             │
│  # 옵션: disabled, highlyrestricted, restricted,           │
│  #       normal, experimental                              │
│                                                             │
└─────────────────────────────────────────────────────────────┘

핵심 정리

개념설명
일련번호 (Seq)전송하는 데이터의 바이트 순서 번호
확인 응답 번호 (Ack)다음에 받기 원하는 바이트 번호
ISN연결 시작 시 사용하는 초기 일련번호 (랜덤)
누적 ACKACK=N은 “N-1까지 모두 받음"을 의미
재전송 제어손실/손상된 데이터를 다시 보내는 메커니즘
RTO재전송 타임아웃 (RTT 기반 계산)
빠른 재전송중복 ACK 3개 시 즉시 재전송
버퍼수신 데이터를 임시 저장하는 공간
오버플로우버퍼 용량 초과 현상
윈도우 크기수신 가능한 데이터 크기 (흐름 제어용)
슬라이딩 윈도우ACK 기다리지 않고 연속 전송하는 기법

전송 과정 요약

┌─────────────────────────────────────────────────────────────┐
│                데이터 전송 핵심 개념                         │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 일련번호 (Sequence Number)                              │
│     ─────────────────────────────────────────               │
│     송신측: "이건 1000번 바이트부터 시작해요"               │
│                                                             │
│  2. 확인 응답 번호 (ACK Number)                             │
│     ─────────────────────────────────────────               │
│     수신측: "1500번부터 보내줘" (1499까지 받았어)           │
│                                                             │
│  3. 재전송                                                  │
│     ─────────────────────────────────────────               │
│     • 타임아웃: 일정 시간 내 ACK 없으면 재전송              │
│     • 빠른 재전송: 중복 ACK 3개면 즉시 재전송               │
│                                                             │
│  4. 흐름 제어 (윈도우)                                      │
│     ─────────────────────────────────────────               │
│     수신측: "4096바이트만 받을 수 있어" → Window=4096       │
│     수신측: "버퍼 가득!" → Window=0 → 전송 중단            │
│     수신측: "다시 비었어" → Window=2000 → 전송 재개        │
│                                                             │
│                                                             │
│  데이터 전송 흐름:                                          │
│  ─────────────────────────────────────────                  │
│                                                             │
│  [송신측]                           [수신측]                │
│      │                                  │                   │
│      │    Seq=1000, Len=500             │                   │
│      ├─────────────────────────────────→│                   │
│      │    "바이트 1000~1499"            │                   │
│      │                                  │                   │
│      │         ACK=1500, Win=3000       │                   │
│      │←─────────────────────────────────┤                   │
│      │    "1500번 보내줘, 3000B 가능"   │                   │
│      │                                  │                   │
│      │    Seq=1500, Len=1000            │                   │
│      ├─────────────────────────────────→│                   │
│      │    "바이트 1500~2499"            │                   │
│      │                                  │                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

용어 정리

  • 일련번호 (Sequence Number): 전송하는 데이터의 바이트 순서를 나타내는 32비트 번호
  • 확인 응답 번호 (Acknowledgment Number): 다음에 받기 원하는 바이트 번호
  • ISN (Initial Sequence Number): 연결 시작 시 사용하는 초기 일련번호 (보안상 랜덤)
  • 재전송 제어 (Retransmission Control): 데이터 손실/손상 시 다시 전송하는 메커니즘
  • RTO (Retransmission Timeout): 재전송을 결정하는 타임아웃 시간
  • RTT (Round Trip Time): 패킷이 왕복하는 데 걸리는 시간
  • 빠른 재전송 (Fast Retransmit): 중복 ACK 3개 수신 시 즉시 재전송
  • 버퍼 (Buffer): 수신한 데이터를 임시 저장하는 메모리 공간
  • 오버플로우 (Overflow): 데이터가 버퍼 용량을 초과하는 현상
  • 윈도우 크기 (Window Size): 수신측이 한 번에 받을 수 있는 데이터 크기
  • 슬라이딩 윈도우 (Sliding Window): ACK를 기다리지 않고 여러 세그먼트를 연속 전송하는 기법
  • 윈도우 스케일링 (Window Scaling): 윈도우 크기를 64KB 이상으로 확장하는 TCP 옵션
  • BDP (Bandwidth-Delay Product): 대역폭 × 지연시간, 최적 버퍼 크기 계산에 사용