전송 제어 프로토콜

IP스택 섬네일 **전송 제어 프로토콜**(**T**ransmission **C**ontrol **P**rotocol, **TCP**, 전송조종규약)은 인터넷 프로토콜 스위트(IP)의 핵심 프로토콜 중 하나로, IP와 함께 *TCP/IP*라는 명칭으로도 널리 불린다. TCP는 근거리 통신망이나 인트라넷, 인터넷에 연결된 컴퓨터에서 실행되는 프로그램 간에 일련의 옥텟을 안정적으로, 순서대로, 에러없이 교환할 수 있게 한다. TCP는 전송 계층에 위치한다. 네트워크의 정보 전달을 통제하는 프로토콜이자 인터넷을 이루는 핵심 프로토콜의 하나로서 국제 인터넷 표준화 기구(IETF)의 RFC 793에 기술되어 있다. TCP는 웹 브라우저들이 월드 와이드 웹에서 서버에 연결할 때 사용되며, 이메일 전송이나 파일 전송에도 사용된다. TCP의 안정성을 필요로 하지 않는 애플리케이션의 경우 일반적으로 TCP 대신 비접속형 사용자 데이터그램 프로토콜(User Datagram Protocol)을 사용한다. 이것은 전달 확인 및 순차 보장 기능이 없는 대신 오버헤드가 작고 지연시간이 짧다는 장점이 있다.
# 기원
1974년 5월 전기 전자 기술자 협회(IEEE)는 “*A Protocol for Packet Network Intercommunication.*”url-status=dead라는 제목의 논문을 발표했다. 저자인 빈트 서프(Vint Cerf)와 밥 칸(Bob Kahn)은 논문에서 노드 간의 정보 공유를 위한 패킷 스위칭 방식의 망간 프로토콜(internetworking protocol)을 제안하였다. 이 모델의 핵심 제어 요소는 연결 지향 링크(connection-oriented links)와 호스트 간의 데이터그램 서비스를 모두 포함하는 *전송 제어 프로그램*(Transmission Control Program) 이었다. 당시 단일한 구성 요소였던 통신 제어 프로그램은 이후 연결 지향 계층의 *통신 제어 프로토콜*(TCP)과 망간(데이터그램) 계층의 *인터넷 프로토콜*(IP)로 나뉘어 모듈식 구조로 변경되었다. 이 모델은 흔히 편의상 두 가지를 합쳐 *TCP/IP*라고 부르며, 공식적인 명칭은 *인터넷 프로토콜 스위트*이다.
# TCP 세그먼트 구조
TCP는 데이터 스트림으로부터 데이터를 받아 들여 이것을 청크 단위로 분할한 뒤 TCP 헤더를 덧붙여 TCP 세그먼트를 생성한다. TCP 세그먼트는 IP 데이터그램에 패킷화되어 상대방과 주고 받게 된다.archive-url=https://web.archive.org/web/20130407215545/http://www.linktionary.com/t/tcp.html *TCP 패킷*이라는 용어가 종종 사용되지만 이는 정확한 표현이 아니다. *세그먼트*가 TCP 프로토콜 데이터 유닛(PDU)을 의미하는 정확한 표현이며 *데이터그램*RFC 791 – section 2.1 은 IP PDU를, *프레임*은 데이터 링크 계층 PDU를 의미한다.

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

TCP 세그먼트는 세그먼트 *헤더*와 *데이터*의 두 섹션으로 구성된다. TCP 헤더는 10개의 필수 필드 및 옵션 확장 필드(표 하단의 주황색 부분)들을 포함한다. 헤더 뒤에는 데이터 섹션이 따라 온다. 그 내용은 애플리케이션의 페이로드 데이터이다. 데이터 섹션의 길이는 TCP 세그먼트 헤더에서 결정되지 않으며, 전체 IP 데이터그램의 길이에서 TCP 헤더와 캡슐화된 IP 헤더의 길이를 뺀 값으로 계산하게 된다. 즉, 데이터 섹션의 길이는 IP 헤더에 의해 결정된다. {| class="wikitable" |+TCP 헤더 |- ! | *오프셋* ! | 옥텟 ! colspan="8" | 0 ! colspan="8" | 1 ! colspan="8" | 2 ! colspan="8" | 3 |- ! | 옥텟 ! `비트`!!` 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` | colspan="16"| Source port || colspan="16"| Destination port |- ! 4 !`32` | colspan="32"| Sequence number |- ! 8 !`64` | colspan="32"| Acknowledgment number (if `ACK` set) |- ! 12 ! `96` | colspan="4"| Data offset || colspan="3"| Reserved
`**0 0 0**` || cellpadding="1"|`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`|| colspan="16"| Window Size |- ! 16 !`128` |colspan="16"| Checksum || colspan="16" | Urgent pointer (`URG` 플래그가 설정된 경우) |- ! 20
... !`160
...` | colspan="32" | Options (*data offset* > 5인 경우. 필요시 끝부분에 "0" 바이트로 패딩 됨.)
... |} ;Source port (16 비트):송신 포트 ;Destination port (16 비트):수신 포트 ;Sequence number (32 비트): :* `SYN` 플래그가 (1)로 설정된 경우, 이것은 초기 시퀀스 번호가 된다. 실제 데이터의 최초 바이트 값과 그에 상응하는 ACK 번호는 이 값에 1을 더한 값이 된다. :* `SYN` 플래그가 (0)으로 해제된 경우, 이것은 현재 세션의 이 세그먼트 데이터의 최초 바이트 값의 누적 시퀀스 번호이다. ;Acknowledgment number (32 비트):`ACK` 플래그가 설정된 경우 이 필드의 값은 수신자가 예상하는 다음 시퀀스 번호이다. 이것은 모든 선행하는 바이트들(존재할 경우)에 대한 수신에 대한 확인응답이 된다. 한쪽이 보낸 최초의 `ACK`는 반대쪽의 초기 시퀀스 번호 자체에 대한 확인응답이 되며, 데이터에 대한 응답은 포함되지 않는다. ;Data offset (4 비트):32-bit 워드 단위로 나타낸 TCP 헤더 크기값이다. 헤더의 최소 크기는 5 워드이며 최대 크기는 15 워드이다. 따라서 최솟값은 20바이트, 최댓값은 60바이트가 되며, 헤더에 선택 값을 위해 최대 40 바이트가 더 추가될 수 있다. 데이터 오프셋이라는 명칭은 이것이 실제 데이터 상에서의 TCP 세그먼트의 시작 위치의 오프셋이기 때문에 붙여졌다. ;Reserved (3 비트):미래에 사용하기 위해 남겨둔 예비 필드이며 0으로 채워져야 한다. ;Flags (9 bits) (혹은 Control bits):9개의 1-비트 플래그를 포함 :* `NS` (1 비트) – ECN-nonce 은폐 보호(RFC 3540에 의해 헤더에 추가). :* `CWR` (1 비트) – 혼잡 윈도 축소(Congestion Window Reduced) 플래그는 송신측 호스트에 의해 설정되는 것으로, 호스트가 `ECE` 플래그가 포함된 TCP 세그먼트를 수신했으며 혼잡 제어 메커니즘에 의해 응답했음을 알리는 역할을 한다(RFC 3168에 의해 헤더에 추가). :* `ECE` (1 비트) – ECN-Echo는 다음을 나타낸다. ::* `SYN` 플래그가 (1)로 설정된 경우, TCP 상대가 명시적 혼잡 통지(Explicit Congestion Notification, ECN)가 가능함을 의미한다. ::* `SYN` 플래그가 (0)으로 해제된 경우, IP 헤더 셋에 혼잡 경험(Congestion Experienced) 플래그가 설정된 패킷이 정상적인 전송 중에 수신되었다는 것을 의미한다(RFC 3168에 의해 헤더에 추가). :* `URG` (1 비트) – Urgent pointer 필드의 값이 유효함을 나타낸다. :* `ACK` (1 비트) – Acknowledgment 필드의 값이 유효함을 나타낸다. 클라이언트가 보낸 최초의 `SYN` 패킷 이후에 전송되는 모든 패킷은 이 플래그가 설정되어 있어야 한다. :* `PSH` (1 비트) – 푸시 기능. 수신 애플리케이션에 버퍼링된 데이터를 푸시해 줄지 여부를 질의하는 역할을 한다. :* `RST` (1 비트) – 커넥션 리셋 :* `SYN` (1 비트) – 동기화 시퀀스 번호. 양쪽이 보낸 최초의 패킷에만 이 플래그가 설정되어 있어야 한다. 다른 일부 플래그들의 의미가 이 플래그의 값에 따라 바뀌며, 일부 플래그들은 이 플래그가 설정되어 있을 때만 유효하고, 또 다른 일부 플래그들은 이 플래그가 해제되어 있을 때에만 유효하다. :* `FIN` (1 비트) – 남은 송신측 데이터 없음 ;Window size (16 비트):*수신 윈도*의 크기. 해당 세그먼트의 송신측이 현재 수신하고자 하는 윈도 크기(기본 단위는 바이트). 수신측은 acknowledgment 필드의 시퀀스 번호부터 수신 윈도의 크기 만큼의 범위 내에서 데이터를 송신측에 보낼 수 있다. ;Checksum (16 비트):헤더 및 데이터의 에러 확인을 위해 사용되는 16 비트 체크섬 필드 ;Urgent pointer (16 비트):`URG` 플래그가 설정된 경우, 이 16 비트 필드는 시퀀스 번호로부터의 오프셋을 나타낸다. 이 오프셋이 마지막 긴급 데이터 바이트를 가리킨다. ;Options (가변 0–320 비트, 32의 배수):이 필드의 길이는 데이터 오프셋 필드에 의해 결정된다. 이 부분은 Option-Kind (1 바이트), Option-Length (1 바이트), Option-Data (가변) 이렇게 최대 3개의 필드로 구성될 수 있다. Option-Kind 필드는 옵션의 종류를 나타내며, 세 가지 필드 중 유일하게 필수값이다. 옵션의 종류에 따라 나머지 두 개의 필드가 설정될 수 있다. Option-Length 필드는 옵션의 전체 길이를 나타내며, Option-Data 필드는 적용 가능한 경우 해당 옵션의 값을 나타낸다. 예를 들어, Option-Kind 바이트 값이 0x01인 경우 이는 패딩의 용도로만 사용되는 옵션없음(No-Op) 옵션을 의미하며, 이 때에는 뒤따라 오는 Option-Length나 Option-Data 값이 존재하지 않는다. Option-Kind 바이트 값이 0인 경우 이는 옵션종료(End Of Options) 옵션을 의미하며, 전자와 마찬가지로 뒤따라 오는 추가 옵션 필드가 없다. Option-Kind 바이트 값이 0x02인 경우 이것은 최대 세그먼트 크기(Maximum Segment Size) 옵션을 의미하며, 그 뒤에는 MSS 필드의 길이값(0x04여야 함)이 따라오게 된다. 이 길이값은 Option-Kind와 Option-Length를 포함한 주어진 옵션 필드의 전체의 길이를 나타내는 것이다. 따라서 MSS 값은 일반적으로 2 바이트로 표현되며, 해당 필드의 길이는 4 바이트(kind와 length의 2바이트를 더한 값)가 된다. 실제 예를 들어 설명하면, 0x05B4라는 값을 갖는 MSS 옵션 필드는 (0x02 0x04 0x05B4)의 형태로 TCP 옵션 섹션에 나타날 것이다. :일부 옵션은 `SYN` 플래그가 설정되어 있을 때에만 송신된다. 이러한 옵션은 아래에 `[SYN]`으로 표시되어 있다. Option-Kind 및 기본 Option-Length는 (Option-Kind, Option-Length)으로 표시되었다. :* 0 (8 비트) – End of options list :* 1 (8 비트) – No operation (NOP, Padding) 이것은 속도 향상을 위해 옵션 필드를 32 비트 길이에 맞추기 위해 사용될 수 있다. :* 2,4,*SS* (32 비트) – Maximum segment size (*최대 세그먼트 크기 참조*) `[SYN]` :* 3,3,*S* (24 비트) – Window scale (*윈도 조정 참조*) `[SYN]`RFC 1323, TCP Extensions for High Performance, Section 2.2 :* 4,2 (16 비트) – Selective Acknowledgement permitted. `[SYN]` (*선택적 확인응답 참조*)RFC 2018, TCP Selective Acknowledgement Options, Section 2 :* 5,*N,BBBB,EEEE,...* (variable bits, *N* is either 10, 18, 26, or 34)- Selective ACKnowledgement (SACK)RFC 2018, TCP Selective Acknowledgement Options, Section 3 이 첫 2 바이트 뒤에는 선택적 확인응답을 받는 1-4개 블럭의 리스트가 따라오게 되며, 이들은 32 비트 시작/종료 포인터로 구분된다. :* 8,10,*TTTT,EEEE* (80 비트)- Timestamp and echo of previous timestamp (*see TCP 타임스탬프 참조*)RFC 1323, TCP Extensions for High Performance, Section 3.2 :* 14,3,*S* (24 비트) – TCP Alternate Checksum Request. `[SYN]`RFC 1146, TCP Alternate Checksum Options :* 15,*N,...* (가변 비트) – TCP Alternate Checksum Data. :(이외의 옵션들은 더 이상 사용되지 않거나, 시험용이거나, 아직 표준화되지 않았거나, 또는 할당되지 않은 것들임) ;Padding:TCP 헤더 패딩은 TCP 헤더의 종료 지점과 데이터의 시작 지점을 32 비트 단위 길이에 맞추기 위해 사용된다. 패딩의 값은 0이다.RFC 793 section 3.1
# 프로토콜의 작동
TCP 프로토콜의 작동은 크게 세 가지 흐름으로 구분한다. # 연결 생성 (Connection establishment) # 자료 전송 (Data transfer) # 연결 종료 (Connection termination) 신뢰성 있는 연결이 생성되어야 하며, 그 후 자료를 전송하고, 마지막으로 연결을 종료하면서 할당된 자원을 반납한다.
## 연결 생성
연결을 생성하기 위해, 3방향 핸드셰이크를 사용한다. **SYN**: 클라이언트가 서버에게 SYN 메시지를 보낸다. 이 메시지에 포함된 시퀀스 번호는 클라이언트가 임의로 설정한 값 A. **SYN-ACK**: 서버가 클라이언트에게 SYN-ACK 메시지로 응답한다. 이 메시지에 포함된 시퀀스 번호는 서버가 임의로 설정한 값 B, 응답 번호는 (A + 1). **ACK**: 클라이언트가 서버에게 ACK 메시지를 보낸다. 이 메시지에 포함된 응답 번호는 (B + 1).
## 연결 종료
연결을 종료하기 위해, 4방향 핸드셰이크를 사용한다.