Skip to content

Transmission Control Protocol

전송 제어 프로토콜(Transmission Control Protocol, TCP, 문화어: 전송조종규약)은 인터넷 프로토콜 스위트(IP)의 핵심 프로토콜 중 하나로, IP와 함께 TCP/IP라는 명칭으로도 널리 불린다. TCP는 근거리 통신망이나 인트라넷, 인터넷에 연결된 컴퓨터에서 실행되는 프로그램 간에 일련의 옥텟을 안정적으로, 순서대로, 에러없이 교환할 수 있게 한다. TCP는 전송 계층에 위치한다. 네트워크의 정보 전달을 통제하는 프로토콜이자 인터넷을 이루는 핵심 프로토콜의 하나로서 국제 인터넷 표준화 기구(IETF)의 RFC 793 에 기술되어 있다.

TCP는 웹 브라우저들이 월드 와이드 웹에서 서버에 연결할 때 사용되며, 이메일 전송이나 파일 전송에도 사용된다.

TCP의 안정성을 필요로 하지 않는 애플리케이션의 경우 일반적으로 TCP 대신 비접속형 사용자 데이터그램 프로토콜(User Datagram Protocol)을 사용한다. 이것은 에러 확인 및 전달 확인 기능이 없는 대신 오버헤드가 작고 지연시간이 짧다는 장점이 있다.

Categories

기원

1974년 5월 전기 전자 기술자 협회(IEEE)는 "A Protocol for Packet Network Intercommunication." 라는 제목의 논문을 발표했다. 저자인 빈트 서프(Vint Cerf)와 밥 칸(Bob Kahn)은 논문에서 노드 간의 정보 공유를 위한 패킷 스위칭 방식의 망간 프로토콜(internetworking protocol)을 제안하였다. 이 모델의 핵심 제어 요소는 연결 지향 링크(connection-oriented links)와 호스트 간의 데이터그램 서비스를 모두 포함하는 전송 제어 프로그램(Transmission Control Program)이었다. 당시 단일한 구성 요소였던 통신 제어 프로그램은 이후 연결 지향 계층의 통신 제어 프로토콜(TCP)과 망간(데이터그램) 계층의 인터넷 프로토콜(IP)로 나뉘어 모듈식 구조로 변경되었다. 이 모델은 흔히 편의상 두 가지를 합쳐 TCP/IP라고 부르며, 공식적인 명칭은 인터넷 프로토콜 스위트이다.

TCP segment structure

TCP는 데이터 스트림으로부터 데이터를 받아 들여 이것을 청크 단위로 분할한 뒤 TCP 헤더를 덧붙여 TCP 세그먼트를 생성한다. TCP 세그먼트는 IP 데이터그램에 캡슐화되어 상대방과 주고 받게 된다.

TCP 패킷이라는 용어가 종종 사용되지만 이는 정확한 표현이 아니다. 세그먼트가 TCP 프로토콜 데이터 유닛(PDU)을 의미하는 정확한 표현이며 데이터그램 은 IP PDU를, 프레임은 데이터 링크 계층 PDU를 의미한다.

프로세스는 TCP를 통해 데이터 버퍼를 인수로 넘겨 줌으로써 데이터를 전송한다. TCP는 이 버퍼들을 묶어 세그먼트를 생성하여 인터넷 모듈(IP 등)을 통해 목적지의 TCP로 각각의 세그먼트들을 전송한다.

TCP 세그먼트는 세그먼트 헤더와 데이터의 두 섹션으로 구성된다. TCP 헤더는 10개의 필수 필드 및 옵션 확장 필드(표 하단의 주황색 부분)들을 포함한다.

헤더 뒤에는 데이터 섹션이 따라 온다. 그 내용은 애플리케이션의 페이로드 데이터이다. 데이터 섹션의 길이는 TCP 세그먼트 헤더에서 결정되지 않으며, 전체 IP 데이터그램의 길이에서 TCP 헤더와 캡슐화된 IP 헤더의 길이를 뺀 값으로 계산하게 된다. 즉, 데이터 섹션의 길이는 IP 헤더에 의해 결정된다.

TCP Header

Offsets

Octet

0

1

2

3

Octet

Bit

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

0

0

Source port

Destination port

4

32

Sequence number

8

64

Acknowledgment number (if ACK set)

12

96

Data offset

Reserved
0 0 0

N
S

|C
W
R

|E
C
E

|U
R
G

|A
C
K

|P
S
H

|R
S
T

|S
Y
N

|F
I
N

Window Size

16

128

Checksum

Urgent pointer (if URG set)

20
...

160
...

Options (if data offset > 5. Padded at the end with "0" bytes if necessary.)
...

혼잡 제어 (Network congestion)

혼잡 제어(congestion control)는 전자 통신 네트워크로 들어가는 정보 소통량을 조절하여 네트워크가 혼잡해지지 않게 조절하는 것을 말한다. 예를 들어, 정보 소통량이 과다한 것을 감지하여 패킷을 적게 보내면 혼잡 붕괴 현상이 일어나는 것을 막을 수 있다.

Head-of-line blocking

해당 항목 참조.

컴퓨터 네트워킹의 HOL 차단(Head-of-Line Blocking)은 첫 번째 패킷이 패킷 라인을 방해할 때 발생하는 성능 제한 현상입니다. 예로는 입력 버퍼링된 네트워크 스위치, 비순차적 전달, HTTP 파이프라이닝의 다중 요청 등이 있습니다.

Packet loss issue

TCP Friendly Rate Control (TFRC)

Status

Socket_status_sequence.png

3 way handshake

4 way handshake

Socket options

자세한 내용은 Network socket#Socket options 항목 참조.

Tcp flags

TCP(Transmission Control Protocol)는 3-WAY Handshake 방식을 통해 두 지점 간에 세션을 연결하여 통신을 시작 하고 4-WAY Handshake를 통해 세션을 종료하여 통신을 종료 합니다. 이러한 세션연결과 해제 이외에도 데이터를 전송하거나 거부, 세션 종료 같은 기능이 패킷의 FLAG 값에 따라 달라지게 되는데, TCP FLAG는 기본적으로 6 가지로 구성됩니다.

FLAG Order

Flag 순서는 아래와 같다.

+-----+-----+-----+----+-----+----+
| URG  | ACK | PSH | RST | SYN | FIN |
+-----+-----+-----+----+-----+----+

각각 1비트로 TCP 세그먼트 필드 안에 cONTROL BIT 또는 FLAG BIT 로 정의 되어 있다.

List of TCP Flags

SYN(Synchronization; 동기화) - S (연결 요청 플래그)
TCP 에서 세션을 성립할 때 가장먼저 보내는 패킷, 시퀀스 번호를 임의적으로 설정하여 세션을 연결하는 데에 사용되며 초기에 시퀀스 번호를 보내게 된다.
ACK(Acknowledgement) - Ack (응답)
상대방으로부터 패킷을 받았다는 걸 알려주는 패킷, 다른 플래그와 같이 출력되는 경우도 있습니다. 받는 사람이 보낸 사람 시퀀스 번호에 TCP 계층에서 길이 또는 데이터 양을 더한 것과 같은 ACK를 보냅니다.(일반적으로 +1 하여 보냄) ACK 응답을 통해 보낸 패킷에 대한 성공, 실패를 판단하여 재전송 하거나 다음 패킷을 전송한다.
RST(Reset) - R (재 연결 종료)
재설정(Reset)을 하는 과정이며 양방향에서 동시에 일어나는 중단 작업이다. 비 정상적인 세션 연결 끊기에 해당한다. 이 패킷을 보내는 곳이 현재 접속하고 있는 곳과 즉시 연결을 끊고자 할 때 사용한다.
PSH(Push) - P (밀어넣기)
TELNET 과 같은 상호작용이 중요한 프로토콜의 경우 빠른 응답이 중요한데, 이 때 받은 데이터를 즉시 목적지인 OSI 7 Layer 의 Application 계층으로 전송하도록 하는 FLAG. 대화형 트랙픽에 사용되는 것으로 버퍼가 채워지기를 기다리지 않고 데이터를 전달한다. 데이터는 버퍼링 없이 바로 위 계층이 아닌 7 계층의 응용프로그램으로 바로 전달한다.
URG(Urgent) - U (긴급 데이터)
Urgent pointer 유효한 것인지를 나타낸다. Urgent pointer란 전송하는 데이터 중에서 긴급히 전당해야 할 내용이 있을 경우에 사용한다. 긴급한 데이터는 다른 데이터에 비해 우선순위가 높아야 한다.
ex) ping 명령어 실행 도중 Ctrl+c 입력
FIN(Finish) - F (연결 종료 요청)
세션 연결을 종료시킬 때 사용되며 더이상 전송할 데이터가 없음을 나타낸다.
Placeholder
패킷의 플래그에 SYN, FINISH, RESET, PUSH등의 플래그가 설정 되어 있지 않은 경우 이 플래그가 세팅된다. 이 플래그는 ACK플래그와 함께 사용되는 경우도 있다.

CSMA/CD

반송파 감지 다중 접속 및 충돌탐지 (영어: Carrier sense multiple access with collision detection, CSMA/CD)는 컴퓨터 네트워크 분야에서 성능개선을 위해 기존의 반송파 감지 다중 접속 방식(CSMA) 을 일정부분 수정한 방식이다.

CSMA/CD 방식은 다음과 같은 특징을 가지고 있다.

  • 반송파를 감지하는 기법을 사용한다.
  • 데이터를 보내고자 하는 송신자 'A' 는 수신자 'B' 가 이미 다른 송신자 'C' 와 통신을 중임을 감지하면 즉시 통신을 중단하고 정체신호 (Jam Signal)을 보낸다. 그리고 임의의 시간 동안 대기하면서 재전송할 준비를 한다.

일단, 정체 신호가 발생하면 송신자 'A' 뿐만 아니라, 수신자 'B' 로 데이터를 보내고자 하는 네트워크 상의 모든 노드 들에게 전달된다. 이로써 불필요한 전송을 사전에 차단시켜 트래픽을 줄인다.

CSMA/CD 방식은 OSI 계층에서 2계층에 속하지만, OSI 7계층 모델의 프로토콜은 아니다.

TCP_NODELAY

  • 분산 시스템의 지연(latency) 문제를 디버깅할 때 가장 먼저 확인해야 하는 항목이 TCP_NODELAY 설정임
  • Nagle 알고리듬은 1984년 RFC896에서 제안된 방식으로, 작은 패킷 전송 시 TCP 헤더 오버헤드를 줄이기 위해 설계됨
  • 그러나 지연된 ACK(delayed ACK) 메커니즘과 결합될 때, 데이터 전송이 ACK 수신까지 지연되어 지연 민감형 애플리케이션의 성능을 악화시킴
  • 현대 데이터센터 환경에서는 RTT가 매우 짧고, 대부분의 시스템이 이미 큰 메시지를 전송하므로 Nagle 알고리듬의 이점이 거의 사라짐
  • 따라서 현대 분산 시스템에서는 TCP_NODELAY를 기본으로 활성화해야 하며, Nagle 알고리듬은 더 이상 필요하지 않음

Nagle 알고리듬의 배경

  • 1984년 John Nagle의 RFC896은 키보드 입력처럼 작은 데이터 전송 시 발생하는 40바이트 헤더 대비 1바이트 데이터의 4000% 오버헤드 문제를 해결하기 위해 제안됨
    • 당시 문제는 사용자가 한 글자씩 입력할 때마다 작은 패킷이 전송되어 네트워크 효율이 낮아지는 현상
    • 해결책은 이전 데이터가 ACK되지 않은 상태에서는 새로운 세그먼트를 전송하지 않도록 제한하는 방식
  • 이 접근은 당시 네트워크 환경에서는 효과적이었으나, 지연 시간(latency) 이 중요한 현대 시스템에는 부적합

Nagle 알고리듬과 Delayed ACK의 상호작용

  • Delayed ACK(RFC813, RFC1122)는 수신 측이 즉시 ACK를 보내지 않고, 응답 데이터가 생기거나 타이머가 만료될 때까지 ACK를 지연시키는 방식
  • Nagle 알고리듬은 ACK를 기다리며 전송을 멈추고, delayed ACK는 ACK를 늦추므로 양쪽이 서로 기다리는 교착 상태가 발생
  • John Nagle 자신도 이 조합을 “끔찍한 조합”이라 표현하며, 두 기능이 독립적으로 도입되었지만 함께 사용될 때 지연을 유발한다고 지적

현대 환경에서의 문제점

  • 데이터센터 내 RTT는 약 500μs, 동일 리전 내에서도 수 밀리초 수준으로 매우 짧음
  • 이런 환경에서 한 RTT만큼 전송을 지연하는 것은 성능 손실로 이어짐
  • 또한 현대 분산 시스템은 TLS, 직렬화, 프로토콜 오버헤드 등으로 인해 이미 충분히 큰 메시지를 전송하므로, 단일 바이트 패킷 문제는 거의 존재하지 않음
  • 작은 메시지 최적화는 이제 애플리케이션 계층에서 처리되고 있음

TCP_NODELAY의 필요성

  • 지연에 민감한 분산 시스템에서는 TCP_NODELAY를 활성화해 Nagle 알고리듬을 비활성화하는 것이 권장됨
    • 이는 “비효율적”이거나 “잘못된 설정”이 아니라, 현대 하드웨어와 트래픽 특성에 맞는 선택
  • 저자는 TCP_NODELAY가 기본값이 되어야 한다고 주장
    • 일부 “write() 호출마다 전송”하는 코드가 느려질 수 있으나, 그런 코드는 근본적으로 수정되어야 함

기타 관련 옵션

  • TCP_QUICKACK 옵션은 ACK 지연을 줄이지만, 이식성 문제와 비일관적 동작으로 인해 근본 해결책이 아님
  • 핵심 문제는 커널이 애플리케이션이 의도한 시점보다 데이터를 오래 보유하는 것이며, write() 호출 시 즉시 전송되어야 함

결론

  • Nagle 알고리듬은 과거 네트워크 효율을 높이기 위한 훌륭한 발명이었으나,
  • 현대의 고속 네트워크와 분산 시스템 환경에서는 오히려 지연을 초래하는 구시대적 기능
  • 따라서 TCP_NODELAY를 항상 활성화하는 것이 현대 시스템 설계의 기본 원칙으로 제시됨

TCP Fast Open

TFO TL;DR

  • TCP Fast Open (TFO) allows clients to send data in the initial SYN request, without waiting for a full handshake to occur. This removes an entire round trip almost transparently from the application.
  • Cookies are included in the TCP options header.
  • It’s available in Linux 3.7+, nginx and HAProxy has support already. Client support is lacking with only Chrome/Chromium on Linux, ChromeOS and Android 5.0 (Lollipop), and only if enabled manually.
  • There’s some potential issues with delivering duplicate data to the server’s application, which wouldn’t occur in normal TCP, although it is unlikely, some applications may not be compatible.
    • It’s perfect for static content (CDNs),
    • Every website which uses TLS (it’ll reduce that handshake time).

Time-wait 의 존재 이유

주로 두가지 이유가 존재한다.

  1. client가 보낸 요청이 유실되었을 때를 대비하기 위해서이다.
  2. client가 서버와 데이터를 교환 후 종료하고, 새로운 connection을 바로 만들게 될 때, 만약 기존 connection과 같은 포트 번호 사용시 서버 입장에서는 이전 connection의 데이터와 이번 connection의 데이터가 혼재할 시 구별할 방법이 없다.
    • Time wait를 하게 될 시 새로운 connection이 진행되어도 이전 포트는 사용 중이므로 client가 새로운 port number를 할당해 구별할 수 있게 된다.

ACK 전송 시나리오

3-way handshake가 완료되지 않은 상태에서 ACK만 보내면 비정상 패킷으로 처리됩니다:

SYN 없이 바로 ACK 전송

클라이언트 → [ACK] → 서버
클라이언트 ← [RST] ← 서버  (연결 거부)
  • 서버는 해당 연결에 대한 상태 정보가 없음
  • RST (Reset) 패킷 응답 → 연결 강제 종료

SYN-ACK를 받지 않고 ACK 전송

정상: SYN → SYN-ACK → ACK
비정상: SYN → [패킷 손실] → ACK (잘못된 ACK 번호)
  • 서버는 예상하지 못한 ACK 번호 수신
  • RST 또는 무시 처리
  • 서버는 SYN-ACK 재전송 타임아웃 대기

잘못된 시퀀스 번호의 ACK

# 서버 입장에서의 검증
if received_ack_num != expected_seq_num + 1:
    # Invalid ACK
    send_RST()  # or ignore

보안 관점

SYN Flood 공격과의 차이:

  • SYN만 보내고 ACK 안 보냄 → 서버 리소스 고갈
  • ACK만 보냄 → 서버가 즉시 RST로 거부하므로 영향 적음

방화벽/IDS 탐지:

  • 비정상 TCP 패킷 패턴으로 감지
  • Spoofed 패킷 가능성으로 차단

결론

TCP 연결 상태 테이블에 없는 ACK는 무효 패킷으로 처리되며, 연결이 성립되지 않습니다. 서버는 RST를 보내거나 무시합니다.

Documentation

RFC 793
TRANSMISSION CONTROL PROTOCOL - RFC Documentation.

See also

Favorite site

Guide

FAQ

References


  1. Evans_Tech_Blog_-_header_of_tcp.pdf 

  2. Overview_of_TCP_flow_control_and_error_control_and_congestion_control_concepts.pdf 

  3. TCP_flow_control_and_error_control_and_congestion_control_example_scenarios.pdf 

  4. KLDP_-TCP_packet_loss-_64kb_large_data_write.pdf 

  5. RFC 5348 

  6. Hellow_world-TCP_IP_Network_stack.pdf 

  7. Understanding TCP/IP Network Stack & Writing Network Apps 

  8. Kernel_Parameter_Decisions_for_TCP_Network_Performance_on_Linux_Servers_-Part_1-Meetup-_TOAST_Cloud.pdf 

  9. Kernel_Parameter_Decisions_for_TCP_Network_Performance_on_Linux_Servers_-Part_2-Meetup-_TOAST_Cloud.pdf 

  10. Kernel_Parameter_Decisions_for_TCP_Network_Performance_on_Linux_Servers_-Part_3-Meetup-_TOAST_Cloud.pdf