Transport Layer - TCP/IP Layer 3
네트워크 계층 (IP)이 호스트 (PC) 간의 데이터 전달을 담당한다면, 전송 계층은 호스트 내에서 실행 중인 어떤 프로세스 (애플리케이션)에게 데이터를 전달할지 결정하고 데이터의 신뢰성을 관리하는 계층이다.
- 멀티플렉싱/디멀티플렉싱: 여러 애플리케이션의 데이터를 묶어 보내거나 (Sender), 받아서 구분해 전달 (Receiver)
- 프로세스 식별: 포트 (Port) 번호 사용
- 신뢰성 및 흐름 제어: TCP 프로토콜 사용
PORT
섹션 제목: “PORT”단일 호스트 내에서 실행되는 프로세스를 구분하는 논리적인 식별자다.
- 16비트 주소 체계로 0 ~ 65535 범위를 가짐
- 하나의 포트는 하나의 프로세스만 점유 가능 (일반적인 경우)
| 포트 종류 | 범위 | 설명 |
|---|---|---|
| Well-known port(System Port) | 0 ~ 1023 | 잘 알려진 포트로, 특정 프로토콜에 할당된 포트(특정 프로토콜) |
| Registered port | 1024 ~ 49151 | 위의 포트보다는 덜 범용적이지만 흔히 사용되는 포트(특정 기업의 애플리케이션) |
| Dynamic port | 49152 ~ 65535 | 사용자가 자유롭게 할당 가능한 포트(크롬 같은 브라우저) |
IANA (Internet Assigned Numbers Authority)에서 관리하고 있으며, 포트 번호에 따라 특정 프로토콜이 할당되어 있다.
IANA
TCP (Transmission Control Protocol)
섹션 제목: “TCP (Transmission Control Protocol)”TCP는 전송 계층의 대표적인 프로토콜로, 신뢰성 있는 데이터 전송을 보장한다.
- 연결 지향 (Connection-oriented): 통신 전 논리적인 연결 통로 (Virtual Circuit) 먼저 생성
- 신뢰성 (Reliability): 패킷 손실, 중복, 순서 바뀜 등을 감지하고 복구
- 세그먼트 (Segment): 데이터를 전송하는 단위
- TCP 헤더와 Payload (애플리케이션 계층에서 전달받은 데이터)로 구성
- MSS (Maximum Segment Size): IP 계층에서의 단편화를 막기 위해 TCP 레벨에서 데이터를 자르는 최대 크기
TCP Segment 헤더 구조
섹션 제목: “TCP Segment 헤더 구조” TCP Segment ┌──────────────────────────────────────────────────┐ │ IP Header │ TCP Header │ TCP Data │ │ (20 bytes) │ (20 bytes) │ │ └──────────────────────────────────────────────────┘
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ┌───────────────────────────┬───────────────────────────┐ │ 발신지 포트 주소 (16) │ 목적지 포트 주소 (16) │ ├───────────────────────────┴───────────────────────────┤ │ Sequence number (32) │ ├───────────────────────────────────────────────────────┤ │ Acknowledgement number (32) │ 20 byte ├────────┬───────┬──────────┬──────────────────────────┤ (우선순위 │ HLEN │ 예약 │U A P R S F│ Window size (16) │ 포함 고정 │(4 bits)│(6 bits)│R C S S Y I│ │ 헤더 길이) │ │ │G K H T N N│ │ ├────────┴───────┴──────────┼──────────────────────────┤ │ Checksum (16) │ Urgent pointer (16) │ ├────────────────────────────┴──────────────────────────┤ │ Options and Padding │ └───────────────────────────────────────────────────────┘헤더는 최소 20바이트에서 옵션에 따라 최대 60바이트까지 가질 수 있다.
- Sequence Number: 데이터의 순서를 보장하기 위한 번호. 전송하는 데이터의 시작 바이트 위치를 나타냄
- Acknowledgement Number (ACK): 다음에 수신하기를 기대하는 바이트 번호 (상대방에게 ‘여기까지 잘 받았다’는 의미)
- Window Size: 수신 측의 버퍼 여유 용량을 알려주어 흐름 제어에 사용
- Control Flags: 6개의 비트로 통신 상태 제어
- SYN: 연결 요청
- ACK: 응답 확인
- FIN: 연결 종료
- RST: 연결 강제 초기화 (비정상 종료 시)
- PSH: 버퍼가 차기를 기다리지 않고 즉시 데이터 전달
- URG: 긴급 데이터 처리
TCP Segment Sequence
섹션 제목: “TCP Segment Sequence”TCP는 전송 순서를 보장하기 위해 Sequence Number와 Acknowledgement Number를 사용하며, 아래와 같은 흐름으로 동작한다.
sequenceDiagram participant A as Host A participant B as Host B A ->> B: Sequence Number 1000 Segment 전송 B ->> A: Acknowledgement Number 1001 요청 A ->> B: Sequence Number 1001 Segment 전송 B ->> A: Acknowledgement Number 1002 요청UDP (User Datagram Protocol)
섹션 제목: “UDP (User Datagram Protocol)”TCP의 복잡한 기능을 제거하고 단순한 데이터 전송에 집중한 프로토콜이다.
UDP Header 구조
섹션 제목: “UDP Header 구조”최소 20바이트에 달하는 TCP 헤더와 달리, UDP 헤더는 단 8바이트로 구성되어 있어 오버헤드가 작다.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 ┌───────────────────────────┬───────────────────────────┐ │ 발신지 포트 주소 (16) │ 목적지 포트 주소 (16) │ ├───────────────────────────┼───────────────────────────┤ │ Length (16) │ Checksum (16) │ └───────────────────────────┴───────────────────────────┘- Source/Destination Port: 송수신 프로세스 식별을 위한 포트 번호
- Length: 헤더와 데이터를 포함한 UDP 데이터그램의 전체 길이
- Checksum: 최소한의 오류 검출을 위한 값
TCP와의 트레이드오프 및 활용 사례
섹션 제목: “TCP와의 트레이드오프 및 활용 사례”UDP는 신뢰성을 포기한 대신 3-Way Handshake 대기 시간과 혼잡 제어 등의 오버헤드를 제거하여 속도를 극대화했다.
- 비연결형 및 비신뢰성
- 핸드셰이크 과정 없이 데이터를 즉시 전송
- 수신 여부 확인 (ACK)이나 순서 보장, 흐름 제어를 하지 않음
- 적용 사례별 채택 이유
- DNS: 요청과 응답 패킷 크기가 매우 작아, 연결 수립 (3-Way Handshake)에 드는 비용이 실제 데이터 전송 비용을 초과하는 상황 방지
- 실시간 스트리밍 및 영상 통화: 패킷이 일부 유실되어 화질이 열화되더라도, TCP처럼 재전송을 기다리며 전체 화면이 멈추는 (버퍼링) 현상을 막는 것이 중요
- HTTP/3 (QUIC): TCP의 구조적 지연 (HOL Blocking)을 피하고자 가벼운 UDP 기반 위에 독자적인 신뢰성 제어를 애플리케이션 수준에서 구현
| TCP | UDP |
|---|---|
| 연결 지향(Connection Oriented) | 비연결 지향(Connectionless) |
| 신뢰성 보장 | 신뢰성 보장 X |
| 순서 보장 | 순서 보장 X |
| 흐름 제어 | 흐름 제어 X |
| 혼잡 제어 | 혼잡 제어 X |
| 느린 성능 | 빠른 성능 |
TCP 연결 관리 (Connection Management)
섹션 제목: “TCP 연결 관리 (Connection Management)”TCP는 안정적인 연결을 위해 3-way Handshake로 연결을 맺고, 4-way Handshake로 연결을 끊는다.
연결 수립: 3-Way Handshake
섹션 제목: “연결 수립: 3-Way Handshake”통신을 시작하기 전, 양쪽의 논리적 연결을 맺고 서로의 시작 Sequence Number (ISN)를 교환하는 과정이다.
sequenceDiagram participant Client participant Server Note over Server: LISTEN (포트 열고 대기) Client ->> Server: 1. [SYN] Seq=x Note over Client: SYN_SENT Note right of Client: 접속 요청 Server ->> Client: 2. [SYN, ACK] Seq=y, Ack=x+1 Note over Server: SYN_RCVD Note left of Server: 요청 수락 및 내 Seq 전송 Client ->> Server: 3. [ACK] Seq=x+1, Ack=y+1 Note over Client: ESTABLISHED Note over Server: ESTABLISHED Note right of Client: 연결 확립연결 해제: 4-Way Handshake
섹션 제목: “연결 해제: 4-Way Handshake”데이터 전송이 끝난 후 리소스를 정리하는 과정이다.
- 양방향 통신이므로 송/수신 연결을 각각 독립적으로 닫음
- 연결 수립 (3-Way)과 달리 4단계가 필요한 이유
- 클라이언트가 종료 요청 (FIN)을 하더라도 서버 측에서는 아직 전송하지 못한 남은 데이터가 있을 수 있음
- 따라서 서버는 먼저 확인 응답 (ACK)을 전송 (
CLOSE_WAIT상태) - 남은 데이터를 모두 전송한 뒤에 자신의 종료 요청 (FIN)을 따로 전송
sequenceDiagram participant Client participant Server Client ->> Server: 1. [FIN] Seq=u Note over Client: FIN_WAIT_1 Note right of Client: 종료 요청 Server ->> Client: 2. [ACK] Seq=v, Ack=u+1 Note over Server: CLOSE_WAIT Note over Client: FIN_WAIT_2 Note left of Server: 종료 확인(남은 데이터 처리) Server ->> Client: 3. [FIN] Seq=w, Ack=u+1 Note over Server: LAST_ACK Note left of Server: 전부 전송 Client ->> Server: 4. [ACK] Seq=u+1, Ack=w+1 Note over Client: TIME_WAIT Note over Server: CLOSED Note right of Client: 확인- TIME_WAIT: 클라이언트가 마지막 ACK를 보내고 일정 시간 (보통 2MSL, 1~2분) 동안 소켓을 닫지 않고 기다리는 상태
- 이유 1: 마지막 ACK가 유실되어 서버가 FIN을 재전송할 경우를 대비
- 이유 2: 네트워크에 떠돌던 지연 패킷이 뒤늦게 도착해 다음 연결의 데이터와 섞이는 것을 방지
TCP 상태와 흐름
섹션 제목: “TCP 상태와 흐름”| 상태 | 설명 |
|---|---|
| CLOSED | 아무런 연결이 없는 상태 |
| LISTEN | SYN 세그먼트를 기다리는 상태, 보통 서버 호스트가 요청을 기다리는 상태 |
| SYN-SENT | SYN 세그먼트를 보낸 뒤 SYN-ACK 세그먼트를 기다리는 상태 |
| SYN-RECEIVED | SYN-ACK 세그먼트를 보낸 뒤 ACK 세그먼트를 기다리는 상태 |
| ESTABLISHED | 연결이 수립된 상태로, Three-way Handshake가 완료되어 데이터를 송수신하는 상태 |
그 외에 FIN-WAIT-1,2 / CLOSE-WAIT / LAST-ACK / TIME-WAIT 는 연결 해제 과정에서 사용되는 상태이며, 종료되면 CLOSED 상태가 된다.
stateDiagram-v2 [*] --> CLOSED CLOSED --> LISTEN: passive open CLOSED --> SYN_SENT: active open / SYN LISTEN --> SYN_RECEIVED: SYN / SYN+ACK LISTEN --> CLOSED: close SYN_SENT --> SYN_RECEIVED: SYN / SYN+ACK SYN_SENT --> ESTABLISHED: SYN+ACK / ACK SYN_SENT --> CLOSED: close SYN_RECEIVED --> ESTABLISHED: ACK SYN_RECEIVED --> FIN_WAIT_1: close / FIN ESTABLISHED --> FIN_WAIT_1: close / FIN ESTABLISHED --> CLOSE_WAIT: FIN / ACK FIN_WAIT_1 --> FIN_WAIT_2: ACK FIN_WAIT_1 --> CLOSING: FIN / ACK FIN_WAIT_1 --> TIME_WAIT: FIN+ACK / ACK FIN_WAIT_2 --> TIME_WAIT: FIN / ACK CLOSING --> TIME_WAIT: ACK TIME_WAIT --> CLOSED: timeout (2MSL) CLOSE_WAIT --> LAST_ACK: close / FIN LAST_ACK --> CLOSED: ACKTCP 신뢰성 보장 메커니즘
섹션 제목: “TCP 신뢰성 보장 메커니즘”신뢰성 있는 데이터 전송을 보장하기 위해 재전송 기반의 오류 제어, 흐름 제어 / 혼잡 제어를 사용한다.
1. 오류 제어 (Error Control) - ARQ (Automatic Repeat Request)
섹션 제목: “1. 오류 제어 (Error Control) - ARQ (Automatic Repeat Request)”TCP는 중복된 ACK 수신이나 타임아웃 발생 시 패킷 유실 (Packet Loss)이나 순서 뒤바뀜 (Out of Order)으로 판단하여 재전송 (Retransmission)을 수행한다.
- 인프라 요인: 수십 개의 라우터 중 단 하나라도 오작동하면 유실이나 순서 바뀜 발생
- 보안 요인: 패킷 필터링 방화벽 등 보안 장비의 개입으로 유실 발생
현대 네트워크와 대부분의 운영체제에서 사용하는 방식은 Selective Repeat ARQ 및 SACK (Selective Acknowledgment)이다.
- Stop-and-Wait ARQ
- 송신자가 데이터를 전송하고, 수신자가 ACK를 전송할 때까지 기다리는 방식
- 제대로 보냈음을 확인하면 다음 데이터를 전송 (전송 -> ACK -> 전송 -> ACK -> …)
- 네트워크 효율이 낮아져 사용하지 않음
- Go-Back-N ARQ (누적 확인 응답, Cumulative Acknowledgment)
- 파이프라이닝 방식으로 여러 개의 세그먼트를 전송하고, 수신자가 올바른 세그먼트에 대해서 ACK를 전송하는 방식
- N번째 패킷 오류 시 N번째 이후의 모든 세그먼트를 폐기 및 재전송하므로 비효율적
- Selective Repeat ARQ 및 SACK (Selective Acknowledgment)
- 오류가 발생한 (유실된) 세그먼트만 콕 집어 재전송하는 방식
- 기존 누적 확인 응답의 한계를 극복하기 위해 SACK 옵션을 도입하여 유실된 특정 패킷만 재전송 요청
- 순서 뒤바뀜 (Out of Order) 발생 시, 즉시 재전송을 요청하기보다 잠시 기다려 불필요한 중복 재전송 방지
2. 흐름 제어 (Flow Control) - Sliding Window
섹션 제목: “2. 흐름 제어 (Flow Control) - Sliding Window”수신 버퍼가 가득 차서 데이터를 처리하지 못하는 상황을 방지하기 위해, 수신 측의 처리 속도에 맞춰 송신 속도를 조절하는 흐름 제어 기술이다.
- 슬라이딩 윈도우: 한 번에 관찰하고 관리하는 데이터의 범위로, 전송량에 따라 크기가 변하고 미끄러지듯이 이동
- 독립적 관리: 윈도우는 클라이언트와 서버 간에 공유되지 않고 각 개체가 독립적으로 관리
슬라이딩 윈도우가 전송의 논리적 범위를 관리한다면, 한 번에 보낼 수 있는 실제 데이터 송신량을 결정하는 핵심 기준은 수신 측의 윈도우 사이즈다.
sequenceDiagram participant Sender as 송신 측 (Sliding Window) participant Receiver as 수신 측 (Window Size)
Note over Receiver: 1. 수신 버퍼 여유 공간 파악<br/>(Window Size = 3) Receiver-->>Sender: ACK 응답 + [Window Size = 3 전달]
Note over Sender: 2. 수신 측이 알려준 크기만큼<br/>송신 측 슬라이딩 윈도우 설정
rect rgb(240, 248, 255) Sender->>Receiver: 패킷 1 전송 Sender->>Receiver: 패킷 2 전송 Sender->>Receiver: 패킷 3 전송 end Note left of Sender: 3. 윈도우 한도(3) 도달<br/>ACK 없이 연속 전송 완료 후 대기
Receiver-->>Sender: 패킷 1에 대한 수신 완료 ACK
Note over Sender: 4. 슬라이딩 윈도우 1칸 이동(Sliding)<br/>새로운 전송 가능 공간 확보
Sender->>Receiver: 패킷 4 전송- 윈도우 사이즈 (Window Size): 수신 측 TCP 버퍼의 여유 공간
- 수신 측은 ACK를 보낼 때 이 윈도우 크기를 헤더에 담아 전송하여 송신 측이 수신 버퍼 상태 파악
- 송신 측은 이 윈도우 크기 내에서 ACK 없이 연속적으로 데이터 전송 가능
제로 윈도우 (Zero Window) 장애와 애플리케이션 설계
섹션 제목: “제로 윈도우 (Zero Window) 장애와 애플리케이션 설계”윈도우 사이즈가 0이 되어 송신 측이 더 이상 데이터를 보낼 수 없는 상태를 제로 윈도우 (Zero Window) 장애라고 한다.
sequenceDiagram participant Sender as 송신 측 participant OS as 수신 측 OS 버퍼 participant App as 애플리케이션
Sender->>OS: 데이터 전송 Note over OS, App: App의 처리 지연으로 버퍼 공간 감소 OS-->>Sender: ACK (Window Size 감소) Sender->>OS: 추가 데이터 전송 Note over OS: 버퍼 가득 참 OS-->>Sender: ACK (Window Size = 0) Note over Sender: 제로 윈도우 발생 (전송 대기) Sender->>OS: 윈도우 갱신 패킷(Probe) 주기적 전송 App->>OS: 뒤늦게 receive 호출 Note over OS: 버퍼 공간 확보 OS-->>Sender: ACK (Window Size 복구) Note over Sender: 데이터 전송 재개- 발생 원인: 네트워크나 OS 문제가 아닌 애플리케이션 프로세스의 처리 지연
- 설계 결함: 애플리케이션이
receive함수 등을 통해 OS 수신 버퍼에서 데이터를 제때 가져가지 못해 버퍼가 가득 참 - 해결 방안: 데이터 수신 로직과 데이터 처리 로직의 분리
- 아키텍처 개선: 단일 수신 스레드가 데이터를 받아 큐 (Queue)에 넣고, 여러 개의 워커 (Worker) 스레드가 병렬로 처리하여 대규모 트래픽 대응
3. 혼잡 제어 (Congestion Control)
섹션 제목: “3. 혼잡 제어 (Congestion Control)”네트워크 자체의 혼잡 상태를 파악하여 송신 속도를 조절하는 기술로, 라우터에 데이터가 몰려 패킷 유실이 발생하는 것을 방지한다.
- Slow Start: 연결 초기에는 패킷을 하나만 보내고, ACK를 받을 때마다 윈도우 크기 (Congestion Window)를 2배씩 지수적으로 증가
- Congestion Avoidance: 특정 임계치 (Threshold)에 도달하면 선형적으로 증가
- Fast Retransmit/Recovery: 타임아웃 전이라도 중복된 ACK가 3번 연속 오면 즉시 재전송하고 윈도우 크기를 줄여 혼잡 상황 대처
결국엔 점진적으로 전송량을 증가 시키고, 최적 안정점까지 도달하면 선형적으로 증가시키며, 혼잡이 발생하면 전송량을 줄이는 방식으로 안정적인 전송률을 유지한다.
TCP 이상 징후와 시스템 장애 (Troubleshooting)
섹션 제목: “TCP 이상 징후와 시스템 장애 (Troubleshooting)”TCP 통신 중 발생하는 재전송 (Retransmission)이나 제로 윈도우 등은 단순한 네트워크 혼잡을 넘어 시스템의 치명적 결함을 알리는 이상 징후로 작용한다.
- 인프라 장애 및 보안 이슈 구분: 수십 개의 라우터 오작동이나 패킷 필터링 방화벽에 의해 순서 뒤바뀜 (Out of Order) 또는 패킷 유실 (Packet Loss) 발생
- 현상 파악: 유실 발생 시 수신 측은 중복 확인 응답 (Duplicate ACK)을 보내 재전송 유도
- 소프트웨어 결함 감지: 윈도우 사이즈가 0이 되는 제로 윈도우는 OS 문제가 아닌 애플리케이션의 receive 함수 호출 지연으로 인한 명백한 설계 오류
- 설계 개선: 대규모 트래픽에 대응하려면 네트워크 수신 스레드와 데이터 처리 워커 스레드를 분리 (큐 사용)하는 아키텍처 도입
TCP와 성능 이슈
섹션 제목: “TCP와 성능 이슈”HTTP는 TCP 위에서 동작하므로 TCP의 구조적 특징이 웹 성능에 직접적인 영향을 준다.
- Handshake Latency: 매 연결마다 3-way handshake가 발생하여 RTT (왕복 시간)가 증가
- 해결: HTTP Keep-Alive를 통해 한 번 맺은 연결을 재사용
- HOL Blocking (Head of Line Blocking): 앞선 패킷이 유실되면 뒤의 패킷들이 멀쩡해도 처리를 못 하고 대기해야 함 (TCP의 순서 보장 특성)
- 해결: HTTP/3 (QUIC)에서는 UDP 기반으로 이를 해결
- Nagle 알고리즘: 작은 패킷을 여러 개 보내는 오버헤드를 줄이기 위해, 버퍼가 찰 때까지 기다렸다가 전송하는 알고리즘
- 문제: 실시간성이 중요한 온라인 게임이나 반응형 웹에서는 지연 (Latency) 유발
- 해결:
TCP_NODELAY옵션으로 Nagle 알고리즘 비활성화