{{위키데이터 속성 추적}}
{{IP스택}}
[[파일:Tcp-handshake.svg|thumb]]
'''전송 제어 프로토콜'''({{lang|en|'''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.''”<ref>{{저널 인용 |url=http://ece.ut.ac.ir/Classpages/F84/PrincipleofNetworkDesign/Papers/CK74.pdf |저자=Vinton G. Cerf, Robert E. Kahn, |제목=''A Protocol for Packet Network Intercommunication'' |저널=IEEE Transactions on Communications |권=22 |호=5 |날짜=1974년 5월 |쪽=637–648 |확인날짜=2013년 8월 20일 |보존url=https://web.archive.org/web/20160304150203/http://ece.ut.ac.ir/Classpages/F84/PrincipleofNetworkDesign/Papers/CK74.pdf |보존날짜=2016년 3월 4일 |url-status=dead }}</ref>라는 제목의 논문을 발표했다. 저자인 빈트 서프(Vint Cerf)와 밥 칸(Bob Kahn)은 논문에서 노드 간의 정보 공유를 위한 [[패킷 스위칭]] 방식의 망간 프로토콜(internetworking protocol)을 제안하였다. 이 모델의 핵심 제어 요소는 연결 지향 링크(connection-oriented links)와 호스트 간의 [[데이터그램]] 서비스를 모두 포함하는 ''전송 제어 프로그램''(Transmission Control Program) 이었다. 당시 단일한 구성 요소였던 통신 제어 프로그램은 이후 [[연결 지향 통신|연결 지향 계층]]의 ''통신 제어 프로토콜''(TCP)과 망간(데이터그램) 계층의 ''인터넷 프로토콜''(IP)로 나뉘어 모듈식 구조로 변경되었다. 이 모델은 흔히 편의상 두 가지를 합쳐 ''TCP/IP''라고 부르며, 공식적인 명칭은 ''[[인터넷 프로토콜 스위트]]''이다.

== TCP 세그먼트 구조 ==
TCP는 데이터 스트림으로부터 데이터를 받아 들여 이것을 청크 단위로 분할한 뒤 TCP 헤더를 덧붙여 TCP 세그먼트를 생성한다. TCP 세그먼트는 [[인터넷 프로토콜|IP 데이터그램]]에 [[네트워크 패킷|패킷]]화되어 상대방과 주고 받게 된다.<ref>{{웹 인용 |url=http://www.linktionary.com/t/tcp.html |제목=TCP (Linktionary term) |확인날짜=2013-08-20 |archive-date=2013-04-07 |archive-url=https://web.archive.org/web/20130407215545/http://www.linktionary.com/t/tcp.html }}</ref>

''TCP 패킷''이라는 용어가 종종 사용되지만 이는 정확한 표현이 아니다. ''세그먼트''가 TCP [[프로토콜 데이터 단위|프로토콜 데이터 유닛(PDU)]]을 의미하는 정확한 표현이며 ''데이터그램''<ref>[http://tools.ietf.org/html/rfc791#section-2.1 RFC 791 – section 2.1]</ref> 은 IP PDU를, ''프레임''은 데이터 링크 계층 PDU를 의미한다.

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

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

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

{| class="wikitable" style="text-align:center"
|+TCP 헤더
|-
! style="border-bottom:none; border-right:none;"| ''오프셋''
! style="border-left:none;"| [[옥텟 (컴퓨팅)|옥텟]]
! colspan="8" | 0
! colspan="8" | 1
! colspan="8" | 2
! colspan="8" | 3
|-
! style="border-top: none" | 옥텟
! <code>[[비트 (단위)|비트]]</code>!!<code>&nbsp;0</code>!!<code>&nbsp;1</code>!!<code>&nbsp;2</code>!!<code>&nbsp;3</code>!!<code>&nbsp;4</code>!!<code>&nbsp;5</code>!!<code>&nbsp;6</code>!!<code>&nbsp;7</code>!!<code>&nbsp;8</code>!!<code>&nbsp;9</code>!!<code>10</code>!!<code>11</code>!!<code>12</code>!!<code>13</code>!!<code>14</code>!!<code>15</code>!!<code>16</code>!!<code>17</code>!!<code>18</code>!!<code>19</code>!!<code>20</code>!!<code>21</code>!!<code>22</code>!!<code>23</code>!!<code>24</code>!!<code>25</code>!!<code>26</code>!!<code>27</code>!!<code>28</code>!!<code>29</code>!!<code>30</code>!!<code>31</code>
|-
! 0
!<code> 0</code>
| colspan="16"| Source port || colspan="16"| Destination port
|-
! 4
!<code>32</code>
| colspan="32"| Sequence number
|-
! 8
!<code>64</code>
| colspan="32"| Acknowledgment number (if <code>ACK</code> set)
|-
! 12
! <code>96</code>
| colspan="4"| Data offset || colspan="3"| Reserved<br /><code>'''0 0 0'''</code> || cellpadding="1"|<code>N<br />S</code>|||<code>C<br />W<br />R</code>|||<code>E<br />C<br />E</code>|||<code>U<br />R<br />G</code>|||<code>A<br />C<br />K</code>|||<code>P<br />S<br />H</code>|||<code>R<br />S<br />T</code>|||<code>S<br />Y<br />N</code>|||<code>F<br />I<br />N</code>|| colspan="16"| Window Size
|-
! 16
!<code>128</code>
|colspan="16"| Checksum || colspan="16" | Urgent pointer (<code>URG</code> 플래그가 설정된 경우)
|-
! 20<br />...
!<code>160<br />...</code>
| colspan="32" style="background:#ffcc88;"| Options (''data offset'' &gt; 5인 경우. 필요시 끝부분에 "0" 바이트로 패딩 됨.)<br />...
|}

;Source port (16 비트):송신 포트
;Destination port (16 비트):수신 포트
;Sequence number (32 비트):
:* <code>SYN</code> 플래그가 (1)로 설정된 경우, 이것은 초기 시퀀스 번호가 된다. 실제 데이터의 최초 바이트 값과 그에 상응하는 ACK 번호는 이 값에 1을 더한 값이 된다.
:* <code>SYN</code> 플래그가 (0)으로 해제된 경우, 이것은 현재 세션의 이 세그먼트 데이터의 최초 바이트 값의 누적 시퀀스 번호이다.
;Acknowledgment number (32 비트):<code>ACK</code> 플래그가 설정된 경우 이 필드의 값은 수신자가 예상하는 다음 시퀀스 번호이다. 이것은 모든 선행하는 바이트들(존재할 경우)에 대한 수신에 대한 확인응답이 된다. 한쪽이 보낸 최초의 <code>ACK</code>는 반대쪽의 초기 시퀀스 번호 자체에 대한 확인응답이 되며, 데이터에 대한 응답은 포함되지 않는다.
;Data offset (4 비트):32-bit 워드 단위로 나타낸 TCP 헤더 크기값이다. 헤더의 최소 크기는 5 워드이며 최대 크기는 15 워드이다. 따라서 최솟값은 20바이트, 최댓값은 60바이트가 되며, 헤더에 선택 값을 위해 최대 40 바이트가 더 추가될 수 있다. 데이터 오프셋이라는 명칭은 이것이 실제 데이터 상에서의 TCP 세그먼트의 시작 위치의 오프셋이기 때문에 붙여졌다.
;Reserved (3 비트):미래에 사용하기 위해 남겨둔 예비 필드이며 0으로 채워져야 한다.
;Flags (9 bits) (혹은 Control bits):9개의 1-비트 플래그를 포함
:* <code>NS</code> (1 비트) – ECN-nonce 은폐 보호(RFC 3540<nowiki/>에 의해 헤더에 추가).
:* <code>CWR</code> (1 비트) – 혼잡 윈도 축소(Congestion Window Reduced) 플래그는 송신측 호스트에 의해 설정되는 것으로, 호스트가 <code>ECE</code> 플래그가 포함된 TCP 세그먼트를 수신했으며 혼잡 제어 메커니즘에 의해 응답했음을 알리는 역할을 한다(RFC 3168<nowiki/>에 의해 헤더에 추가).
:* <code>ECE</code> (1 비트) – ECN-Echo는 다음을 나타낸다.
::* <code>SYN</code> 플래그가 (1)로 설정된 경우, TCP 상대가 명시적 혼잡 통지(Explicit Congestion Notification, ECN)가 가능함을 의미한다.
::* <code>SYN</code> 플래그가 (0)으로 해제된 경우, IP 헤더 셋에 혼잡 경험(Congestion Experienced) 플래그가 설정된 패킷이 정상적인 전송 중에 수신되었다는 것을 의미한다(RFC 3168<nowiki/>에 의해 헤더에 추가).
:* <code>URG</code> (1 비트) – Urgent pointer 필드의 값이 유효함을 나타낸다.
:* <code>ACK</code> (1 비트) – Acknowledgment 필드의 값이 유효함을 나타낸다. 클라이언트가 보낸 최초의 <code>SYN</code> 패킷 이후에 전송되는 모든 패킷은 이 플래그가 설정되어 있어야 한다.
:* <code>PSH</code> (1 비트) – 푸시 기능. 수신 애플리케이션에 버퍼링된 데이터를 푸시해 줄지 여부를 질의하는 역할을 한다.
:* <code>RST</code> (1 비트) – 커넥션 리셋
:* <code>SYN</code> (1 비트) – 동기화 시퀀스 번호. 양쪽이 보낸 최초의 패킷에만 이 플래그가 설정되어 있어야 한다. 다른 일부 플래그들의 의미가 이 플래그의 값에 따라 바뀌며, 일부 플래그들은 이 플래그가 설정되어 있을 때만 유효하고, 또 다른 일부 플래그들은 이 플래그가 해제되어 있을 때에만 유효하다.
:* <code>FIN</code> (1 비트) – 남은 송신측 데이터 없음
;Window size (16 비트):''수신 윈도''의 크기. 해당 세그먼트의 송신측이 현재 수신하고자 하는 윈도 크기(기본 단위는 바이트). acknowledgment 필드의 시퀀스 번호보다 큰 값이어야 한다.
;Checksum (16 비트):헤더 및 데이터의 에러 확인을 위해 사용되는 16 비트 [[체크섬]] 필드
;Urgent pointer (16 비트):<code>URG</code> 플래그가 설정된 경우, 이 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 옵션 섹션에 나타날 것이다.
:일부 옵션은 <code>SYN</code> 플래그가 설정되어 있을 때에만 송신된다. 이러한 옵션은 아래에 <sup><tt style="color:#000; background:#ccc;">[SYN]</code></sup>으로 표시되어 있다. 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 (''[[#최대 세그먼트 크기|최대 세그먼트 크기]] 참조'') <sup><tt style="color:#000; background:#ccc;">[SYN]</code></sup>
:* 3,3,''S'' (24 비트) – Window scale (''[[#윈도 조정|윈도 조정]] 참조'') <sup><tt style="color:#000; background:#ccc;">[SYN]</code></sup><ref>[http://tools.ietf.org/html/rfc1323#page-9 RFC 1323, TCP Extensions for High Performance, Section 2.2]</ref>
:* 4,2 (16 비트) – Selective Acknowledgement permitted. <sup><tt style="color:#000; background:#ccc;">[SYN]</code></sup> (''[[#선택적 확인응답|선택적 확인응답]] 참조'')<ref>[http://tools.ietf.org/html/rfc2018#section-2 RFC 2018, TCP Selective Acknowledgement Options, Section 2]</ref>
:* 5,''N,BBBB,EEEE,...'' (variable bits, ''N'' is either 10, 18, 26, or 34)- Selective ACKnowledgement (SACK)<ref>[http://tools.ietf.org/html/rfc2018#section-3 RFC 2018, TCP Selective Acknowledgement Options, Section 3]</ref> 이 첫 2 바이트 뒤에는 선택적 확인응답을 받는 1-4개 블럭의 리스트가 따라오게 되며, 이들은 32 비트 시작/종료 포인터로 구분된다.
:* 8,10,''TTTT,EEEE'' (80 비트)- Timestamp and echo of previous timestamp (''see [[#TCP 타임스탬프|TCP 타임스탬프]] 참조'')<ref>[http://tools.ietf.org/html/rfc1323#page-11 RFC 1323, TCP Extensions for High Performance, Section 3.2]</ref>
:* 14,3,''S'' (24 비트) – TCP Alternate Checksum Request. <sup><tt style="color:#000; background:#ccc;">[SYN]</code></sup><ref>[http://tools.ietf.org/html/rfc1146#page-2 RFC 1146, TCP Alternate Checksum Options]</ref>
:* 15,''N,...'' (가변 비트) – TCP Alternate Checksum Data.
:(이외의 옵션들은 더 이상 사용되지 않거나, 시험용이거나, 아직 표준화되지 않았거나, 또는 할당되지 않은 것들임)
;Padding:TCP 헤더 패딩은 TCP 헤더의 종료 지점과 데이터의 시작 지점을 32 비트 단위 길이에 맞추기 위해 사용된다. 패딩의 값은 0이다.<ref>RFC 793 section 3.1</ref>

== 프로토콜의 작동 ==
TCP 프로토콜의 작동은 크게 세 가지 흐름으로 구분한다.
# 연결 생성 (Connection establishment)
# 자료 전송 (Data transfer)
# 연결 종료 (Connection termination)

신뢰성 있는 연결이 생성되어야 하며, 그 후 자료를 전송하고, 마지막으로 연결을 종료하면서 할당된 자원을 반납한다.

=== 연결 생성 ===
연결을 생성하기 위해, 3방향 핸드셰이크를 사용한다.

'''SYN''': 클라이언트가 서버에게 SYN 메시지를 보낸다. 이 메시지에 포함된 시퀀스 번호는 클라이언트가 임의로 설정한 값 A.

'''SYN-ACK''': 서버가 클라이언트에게 SYN-ACK 메시지로 응답한다. 이 메시지에 포함된 시퀀스 번호는 서버가 임의로 설정한 값 B, 응답 번호는 (A + 1).

'''ACK''': 클라이언트가 서버에게 ACK 메시지를 보낸다. 이 메시지에 포함된 응답 번호는 (B + 1).

=== 연결 종료 ===
연결을 종료하기 위해, 4방향 핸드셰이크를 사용한다.

== 각주 ==
<references />

== 외부 링크 ==

*RFC 675 – 인터넷 전송 제어 프로그램 규격, 1974년 12월 판
*RFC 793 – TCP v4
*RFC 1122 – TCP 관련 일부 오류 수정
*RFC 1323 – TCP 확장
*RFC 1379 – 트랜잭션 콘셉트 관련 TCP 확장
*RFC 1948 – 시퀀스 번호 공격 방어
*RFC 2018 – TCP 선택적 확인응답 옵션
*RFC 4614 – TCP 규격 문서 로드맵
*RFC 5681 – TCP 혼잡 제어
*RFC 6298 – TCP 재전송 타이머 계산
*RFC 6824 - 다중주소 환경의 다중경로 동작을 위한 TCP 확장

[[분류:인터넷 표준]]
[[분류:인터넷 프로토콜]]
[[분류:전송 계층 프로토콜]]