이 문서의 과거 버전 (r1)을 보고 있습니다. 수정일: 2026.02.12 06:22
TCP 세그먼트 구조는 전송 제어 프로토콜(TCP)이 데이터를 전송하기 위해 사용하는 기본 단위인 TCP 세그먼트의 내부 구성 방식을 설명한다. TCP는 인터넷 프로토콜 스위트의 핵심 프로토콜 중 하나로, 신뢰성 있는 연결형 통신을 제공한다. 이 신뢰성 있는 데이터 전송은 모든 정보가 정해진 구조를 가진 세그먼트에 담겨 교환됨으로써 이루어진다.
TCP 세그먼트는 크게 헤더와 데이터 부분으로 나뉜다. 헤더에는 연결 관리, 데이터 정렬, 오류 검출, 흐름 제어, 혼잡 제어 등에 필요한 다양한 제어 정보가 포함되어 있다. 데이터 부분은 실제로 상위 계층(예: HTTP, FTP)에서 내려받은 애플리케이션 데이터, 즉 페이로드가 위치한다. 세그먼트 구조는 RFC 793을 비롯한 표준 문서에 정의되어 있으며, 모든 TCP 구현체는 이 구조를 준수한다.
이 구조는 TCP가 제공하는 핵심 서비스인 신뢰적 전송, 순서 보장, 흐름 제어, 혼잡 제어의 기반이 된다. 예를 들어, 헤더 내의 시퀀스 번호와 확인 응답 번호는 데이터의 순서와 누락을 관리하며, 윈도우 크기 필드는 수신자의 처리 능력에 맞춘 흐름 제어를 가능하게 한다. 따라서 TCP 세그먼트 구조를 이해하는 것은 TCP 프로토콜의 동작 원리를 파악하는 첫걸음이다.
TCP 세그먼트의 TCP 헤더는 데이터 전송을 제어하는 데 필요한 모든 정보를 담고 있으며, 일반적으로 20바이트의 기본 헤더와 최대 40바이트의 옵션 필드로 구성된다. 이 구조는 RFC 793에 정의되어 있으며, 네트워크를 통해 전송되는 모든 TCP 세그먼트의 시작 부분에 위치한다. 헤더의 각 필드는 송신자와 수신자 간의 연결 상태 관리, 데이터의 순서 보장, 흐름 제어, 오류 검출 등의 기능을 수행하는 데 사용된다.
기본 헤더는 다음과 같은 고정된 20바이트의 필드들로 이루어져 있다.
필드 이름 | 크기(비트) | 설명 |
|---|---|---|
송신 포트 번호 | 16 | 세그먼트를 보내는 애플리케이션의 포트 번호 |
수신 포트 번호 | 16 | 세그먼트를 받는 애플리케이션의 포트 번호 |
시퀀스 번호 | 32 | 전송 중인 데이터 바이트 스트림 내 위치를 식별 |
확인 응답 번호 | 32 | 다음에 수신하기를 기대하는 바이트의 시퀀스 번호 |
데이터 오프셋 | 4 | TCP 헤더의 길이를 32비트 워드 단위로 표시 |
예약 | 6 | 미래 사용을 위해 예약되어 있으며 0으로 설정 |
제어 비트(플래그) | 6 | 연결 제어 및 상태를 나타내는 플래그 비트 |
윈도우 크기 | 16 | 수신 측의 가용 수신 버퍼 공간을 알리는 흐름 제어 값 |
체크섬 | 16 | 헤더와 데이터의 오류를 검출하기 위한 값 |
긴급 포인터 | 16 | 긴급 데이터가 존재할 경우 그 위치를 가리킴 |
데이터 오프셋 필드 뒤에는 가변 길이의 옵션 필드가 올 수 있다. 이 필드는 기본 헤더 기능을 확장하는 데 사용되며, 최대 세그먼트 크기 협상, 선택적 확인응답, 타임스탬프 사용과 같은 고급 기능을 지원한다. 옵션 필드의 길이는 32비트 경계에 맞추기 위해 필요한 경우 패딩으로 끝나며, 전체 TCP 헤더 길이는 데이터 오프셋 값에 4를 곱한 바이트 수가 된다.
TCP 세그먼트의 기본 헤더는 통신에 필요한 핵심 정보를 담고 있으며, 고정적으로 20바이트의 크기를 가진다. 이 구조는 RFC 793에 정의되어 있으며, 모든 TCP 세그먼트는 이 기본 헤더를 반드시 포함한다.
기본 헤더는 다음의 필드들로 구성된다.
필드 (16비트 단위) | 설명 |
|---|---|
송신 포트 번호 | 세그먼트를 보내는 애플리케이션의 포트 번호이다. |
수신 포트 번호 | 세그먼트를 받을 애플리케이션의 포트 번호이다. |
시퀀스 번호 | 전송 중인 데이터 바이트 스트림 내에서 이 세그먼트의 첫 번째 바이트 위치를 나타낸다. |
확인 응답 번호 | 수신 측이 다음에 기대하는 시퀀스 번호를 나타내며, 데이터 수신 확인에 사용된다. |
데이터 오프셋 | TCP 헤더의 길이를 32비트 워드 단위로 표시한다. 이는 헤더의 시작부터 데이터의 시작 위치까지의 오프셋을 결정한다. |
예약 | 미래 사용을 위해 예약된 비트 영역이며, 0으로 설정된다. |
제어 비트 | 연결 제어 및 상태를 나타내는 9개의 플래그 비트를 포함한다[1]. |
윈도우 크기 | 수신 측의 가용 수신 버퍼 공간을 바이트 단위로 알려주어 흐름 제어를 수행한다. |
체크섬 | 헤더, 데이터, 의사 헤더를 포함한 세그먼트 전체의 오류 검출을 위한 값이다. |
긴급 포인터 | URG 플래그가 설정된 경우, 긴급 데이터의 끝 위치를 시퀀스 번호에 상대적으로 가리킨다. |
이러한 필드들은 3-way 핸드셰이크를 통한 연결 설정, 데이터의 순서 있는 전달, 흐름 제어, 오류 검출 등 TCP의 핵심 기능을 지원하는 기반이 된다. 옵션 필드가 추가되면 헤더 길이는 20바이트를 초과할 수 있으나, 기본 헤더의 구조와 필드 순서는 변하지 않는다.
TCP 헤더의 기본 길이는 20바이트이지만, 필요에 따라 옵션 필드를 추가하여 최대 40바이트까지 확장할 수 있다. 이 옵션 필드는 TCP 연결의 다양한 고급 기능과 협상을 위해 사용된다.
옵션 필드는 종류-길이-값(Kind-Length-Value, KLV) 형식으로 구성된다. 주요 옵션 종류와 그 기능은 다음과 같다.
옵션 종류(Kind) | 이름 | 설명 |
|---|---|---|
0 | End of Option List | 옵션 목록의 끝을 표시한다. |
1 | No-Operation (NOP) | 옵션 필드의 정렬(패딩)을 위해 사용된다. |
2 | Maximum Segment Size (MSS) | 연결 설정 과정에서 상대방에게 알리는 자신이 수신할 수 있는 최대 세그먼트 크기이다. |
3 | Window Scale | 윈도우 크기 필드의 값을 왼쪽으로 시프트하여 실제 윈도우 크기를 확장한다. |
4 | Selective Acknowledgment Permitted (SACK Permitted) | 선택적 확인응답 기능 사용 가능을 협상한다. |
5 | Selective Acknowledgment (SACK) | 수신된 불연속 데이터 블록의 범위를 알려준다. |
8 | Timestamps | 패킷의 왕복 시간(RTT) 측정과 시퀀스 번호 순환(PAWS) 방지에 사용된다. |
옵션 필드는 32비트(4바이트) 경계에 정렬되어야 한다. 이를 위해 필요시 NOP 옵션을 패딩으로 삽입한다. 옵션 협상은 주로 3방향 핸드셰이크 과정에서 이루어지며, 일단 협상된 옵션은 연결이 유지되는 동안 사용된다. 예를 들어, 윈도우 스케일 옵션은 초기 핸드셰이크에서만 교환될 수 있다.
TCP 세그먼트의 헤더에는 출발지 포트 번호 필드와 목적지 포트 번호 필드가 각각 16비트로 포함되어 있다. 이 두 필드는 전송 계층에서 호스트 내의 특정 프로세스나 서비스를 식별하는 데 사용되는 주소 역할을 한다.
포트 번호는 0부터 65535까지의 값을 가질 수 있다. 이 범위는 잘 알려진 포트(0-1023), 등록된 포트(1024-49151), 동적/사설 포트(49152-65535)로 구분된다. 예를 들어, HTTP는 80번, HTTPS는 443번, DNS는 53번과 같은 잘 알려진 포트를 사용한다. 하나의 IP 주소와 포트 번호의 조합은 네트워크 소켓을 고유하게 정의한다.
TCP 연결은 출발지 IP 주소, 출발지 포트, 목적지 IP 주소, 목적지 포트라는 네 가지 요소로 구성된 4-튜플에 의해 식별된다. 따라서 동일한 두 호스트 간에 동일한 포트 쌍을 사용하는 복수의 동시 연결은 일반적으로 불가능하다. 포트 번호는 TCP 헤더의 가장 앞부분에 위치하여, 패킷이 목적지 호스트에 도착했을 때 운영체제가 해당 세그먼트를 올바른 응용 프로그램에 전달할 수 있도록 한다.
시퀀스 번호는 송신 스트림 내에서 전송되는 데이터의 첫 번째 바이트 위치를 식별하는 32비트 값이다. 각 TCP 세그먼트는 자신이 담고 있는 데이터의 시작 바이트 번호를 시퀀스 번호 필드에 명시한다. 이를 통해 수신 측은 세그먼트들이 올바른 순서로 도착했는지 확인하고, 중복되거나 손실된 데이터를 감지할 수 있다. 연결이 시작될 때 초기 시퀀스 번호는 무작위 값으로 설정되며, 이후 전송된 데이터 바이트 수만큼 증가한다[2].
확인 응답 번호는 32비트 필드로, 수신 측이 성공적으로 수신한 데이터의 다음 바이트 번호를 송신 측에 알리는 데 사용된다. 이는 '다음에 수신을 기대하는 시퀀스 번호'를 의미하며, 신뢰성 있는 데이터 전송의 핵심 메커니즘인 긍정 확인 응답을 구현한다. 예를 들어, 수신 측이 시퀀스 번호 1000으로 시작하는 200바이트의 세그먼트를 받았다면, 확인 응답 번호로 1200을 설정하여 송신 측에 1199번 바이트까지 정상 수신되었음을 통보한다.
두 필드는 3방향 핸드셰이크 과정에서도 중요한 역할을 한다. 연결 설정 시, 양측은 자신의 초기 시퀀스 번호를 상대방에게 알리고, 상대방의 시퀀스 번호에 대한 확인 응답을 보낸다. 이 과정을 통해 양방향 통신 채널의 초기 동기화가 이루어진다.
필드 | 크기 | 주요 역할 |
|---|---|---|
시퀀스 번호 | 32비트 | 전송 데이터의 시작 바이트 위치 식별 |
확인 응답 번호 | 32비트 | 성공적으로 수신된 데이터의 다음 바이트 번호 통지 |
이러한 번호 체계는 슬라이딩 윈도우 프로토콜과 결합되어 흐름 제어 및 혼잡 제어의 기반을 제공한다. 또한, 시퀀스 번호의 예측 불가능한 초기화는 TCP 스푸핑과 같은 보안 공격을 어렵게 만드는 요소 중 하나이다.
데이터 오프셋 필드는 TCP 헤더의 길이를 4바이트 단위로 나타내는 4비트 필드이다. 이 값은 TCP 세그먼트의 시작 지점에서 실제 데이터가 시작되는 위치까지의 오프셋을 지정한다.
데이터 오프셋의 최소값은 5이며, 이는 기본 헤더 길이인 20바이트(5 * 4바이트)에 해당한다. 최대값은 15로, 헤더의 최대 길이는 60바이트(15 * 4바이트)까지 가능하다. 이 60바이트 제한은 TCP 옵션 필드가 최대 40바이트까지 사용될 수 있음을 의미한다[3].
수신 측은 이 필드의 값을 읽어 TCP 헤더의 정확한 종료 지점과 데이터 페이로드의 시작 지점을 식별한다. 옵션 필드의 존재 여부와 길이에 따라 헤더의 전체 크기가 가변적이므로, 데이터 오프셋은 페이로드의 위치를 결정하는 데 필수적인 정보이다.
제어 비트 필드는 TCP 헤더의 6번째 16비트 워드에 위치한 9비트(기본 6비트 + 확장 3비트) 공간으로, TCP 연결의 상태를 관리하고 데이터 전송의 특성을 제어하는 데 사용된다. 이 비트들은 각각 독립적으로 설정될 수 있으며, 특정 비트가 1로 설정되면 해당 기능이 활성화됨을 의미한다.
기본 �어더에 포함된 6개의 주요 플래그는 다음과 같다.
플래그 | 설명 |
|---|---|
URG (Urgent) | 긴급 포인터 필드가 유효함을 나타낸다. 이 플래그가 설정되면 수신 측은 긴급 데이터를 우선적으로 처리한다. |
ACK (Acknowledgment) | 확인 응답 번호 필드가 유효함을 나타낸다. 연결 성립 후 거의 모든 세그먼트에서 이 플래그가 설정된다. |
PSH (Push) | 수신 측에게 버퍼링 없이 데이터를 즉시 상위 계층(애플리케이션 계층)으로 전달하도록 요청한다. |
RST (Reset) | 연결을 강제로 재설정한다. 비정상적인 상황이나 오류 발생 시 사용된다. |
SYN (Synchronize) | 연결 설정을 초기화하는 데 사용된다. 시퀀스 번호를 동기화한다. |
FIN (Finish) | 송신 측의 데이터 전송이 종료되었음을 알리고 연결 종료를 시작한다. |
확장된 플래그로는 ECN(Explicit Congestion Notification) 관련 비트인 ECE와 CWR이 있다. ECE 비트는 상대방이 ECN을 지원함을 나타내거나 혼잡을 경고하는 데 사용되며, CWR 비트는 혼잡 윈도우 크기가 감소되었음을 송신 측이 알릴 때 사용된다[4]. NS 비트는 실험적 용도로 정의되어 있다. 이 플래그들을 조합하여 3방향 핸드셰이크 및 4방향 핸드셰이크와 같은 연결 설정 및 종료 절차가 수행된다.
연결 제어 플래그는 TCP 연결의 수립, 유지, 종료 과정을 관리하는 데 사용되는 비트들이다. 이 플래그들은 3방향 핸드셰이크 및 4방향 핸드셰이크 과정에서 핵심적인 역할을 수행한다.
주요 연결 제어 플래그는 다음과 같다.
플래그 | 이름 | 설명 |
|---|---|---|
SYN | Synchronize | 연결 설정을 시작할 때 사용된다. 시퀀스 번호를 동기화한다. |
ACK | Acknowledgment | 확인 응답을 나타낸다. 유효한 확인 응답 번호를 포함한다는 의미이다. |
FIN | Finish | 연결 종료를 요청할 때 사용된다. 데이터 전송을 완료했음을 알린다. |
연결 수립 단계에서는 클라이언트가 SYN 플래그가 설정된 세그먼트를 전송한다. 서버는 이에 응답하여 SYN과 ACK 플래그가 모두 설정된 세그먼트로 회신한다. 마지막으로 클라이언트가 ACK 플래그를 설정한 세그먼트를 보내면 연결이 성립된다[5]. 연결 종료 시에는 한쪽이 FIN 플래그를 설정한 세그먼트를 보내고, 상대방은 이에 대해 ACK로 응답한 후 자신의 FIN 세그먼트를 전송한다. 최종 ACK 확인을 통해 연결이 완전히 종료된다.
TCP 헤더의 제어 비트 필드 중 데이터 전송과 관련된 주요 플래그는 PSH 플래그와 URG 플래그이다. 이 플래그들은 애플리케이션 계층으로의 데이터 전달 시점이나 특정 데이터의 처리 우선순위를 제어하는 역할을 한다.
PSH 플래그는 송신 측에서 설정되며, 수신 측 TCP에게 버퍼링된 데이터를 지체 없이 즉시 상위 애플리케이션에 전달하도록 지시한다. 일반적으로 TCP는 효율성을 위해 일정량의 데이터를 버퍼에 모아 전달하지만, PSH 플래그가 설정된 세그먼트를 수신하면 해당 데이터와 함께 버퍼에 대기 중인 모든 데이터를 즉시 애플리케이션에 푸시(push)한다. 이는 대화형 애플리케이션(예: 텔넷, 실시간 채팅)에서 사용자의 입력을 즉시 전송해야 할 때 유용하게 활용된다.
URG 플래그는 긴급 데이터의 존재를 나타내며, 긴급 포인터 필드와 함께 동작한다. 이 플래그가 설정되면, 세그먼트의 데이터 페이로드 내 일부 바이트가 긴급 데이터임을 의미한다. 긴급 포인터는 시퀀스 번호를 기준으로 한 오프셋 값으로, 긴급 데이터의 끝 위치를 가리킨다. 수신 측 TCP는 이 플래그를 확인하면 정상적인 데이터 스트림 순서와 관계없이 긴급 데이터를 우선적으로 애플리케이션에 알린다. 그러나 현대 네트워크 프로그래밍에서는 이 메커니즘 대신 별도의 제어 채널(예: 대역외 데이터)을 사용하는 경우가 많다.
플래그 | 이름 | 용도 |
|---|---|---|
PSH | Push | 버퍼링 없이 데이터를 즉시 애플리케이션에 전달하도록 지시 |
URG | Urgent | 세그먼트 내에 긴급 데이터가 포함되어 있음을 표시 |
윈도우 크기 필드는 16비트로 구성되어 있으며, 흐름 제어를 수행하는 핵심 매커니즘이다. 이 필드의 값은 송신자가 현재 수신할 수 있는 데이터의 양, 즉 수신 윈도우의 크기를 바이트 단위로 상대방에게 알린다. 이를 통해 수신 측의 버퍼 상태에 따라 데이터 전송 속도를 동적으로 조절하여, 버퍼 오버플로우를 방지하고 효율적인 데이터 전송을 가능하게 한다.
윈도우 크기의 값은 슬라이딩 윈도우 프로토콜의 기반이 된다. 송신 측은 수신 측으로부터 확인 응답을 받지 않은 상태에서도, 수신 측이 통보한 윈도우 크기만큼의 데이터를 연속적으로 전송할 수 있다. 수신 측이 데이터를 처리하고 버퍼 공간이 생기면, 새로운 ACK 세그먼트에 업데이트된 윈도우 크기 값을 담아 보내며, 이에 따라 송신 측의 전송 가능 윈도우가 이동하고 확장된다.
용어 | 설명 |
|---|---|
수신 측이 현재 수용 가능한 데이터의 양. TCP 헤더의 윈도우 크기 필드에 실린다. | |
네트워크의 혼잡 상태를 고려하여 송신 측이 내부적으로 유지하는 전송량 제한. 헤더 필드에 직접 표시되지 않는다. | |
송신 측이 실제로 한 번에 보낼 수 있는 데이터 양. 수신 윈도우와 혼잡 윈도우 중 작은 값에 의해 결정된다. |
16비트 필드의 한계로 인해 최대 윈도우 크기는 65,535바이트로 제한되었으나, 대역폭이 높은 현대 네트워크에서는 이 크기로는 효율적인 전송이 어려웠다. 이 문제를 해결하기 위해 윈도우 스케일 옵션이 도입되었다. 이 옵션을 사용하면 셰이크핸드 과정에서 협상된 스케일 팩터를 통해 윈도우 크기 값을 좌측으로 시프트하여 최대 1기가바이트에 가까운 매우 큰 윈도우 크기를 지원할 수 있게 되었다.
체크섬 필드는 TCP 세그먼트의 무결성을 검증하기 위해 사용되는 16비트 필드이다. 이 필드는 세그먼트 헤더, 데이터 페이로드, 그리고 의사 헤더로 구성된 계산 범위에 대한 1의 보수 합의 결과값을 담는다. 수신 측은 동일한 알고리즘으로 체크섬을 다시 계산하고, 계산된 값이 0이 아니면 패킷이 손상되었다고 판단하여 해당 세그먼트를 폐기한다.
체크섬 계산에 포함되는 의사 헤더는 IP 헤더의 출발지 주소, 목적지 주소, 프로토콜 값, 그리고 TCP 세그먼트 전체 길이 정보로 구성된다. 이는 전송 중 IP 주소가 변경되거나 프로토콜이 변조되는 경우를 감지할 수 있게 해준다. 따라서 체크섬은 단순히 TCP 데이터의 오류뿐만 아니라, 네트워크 계층에서의 일부 오류도 함께 검출하는 역할을 수행한다.
계산 범위 구성 요소 | 설명 |
|---|---|
의사 헤더 | 출발지/목적지 IP 주소, 프로토콜 번호, TCP 세그먼트 길이 |
TCP 헤더 | 소스/목적지 포트, 시퀀스 번호 등 모든 헤더 필드 (체크섬 필드 자리는 0으로 설정) |
데이터 페이로드 | 실제 전송할 데이터 (패딩 바이트 포함) |
체크섬 검사는 엔드 투 엔드 원리에 기반한 신뢰성 보장 메커니즘의 핵심 요소이다. 하드웨어 기반의 CRC 오류 검출이 링크 계층에서 일반적으로 사용되지만, TCP 체크섬은 라우터나 스위치와 같은 중간 노드에서 발생할 수 있는 소프트웨어 처리 오류까지 감지하는 추가적인 보호 계층을 제공한다[6].
긴급 포인터는 TCP 헤더 내의 16비트 필드로, 긴급 데이터의 위치를 가리킨다. 이 필드는 제어 비트 중 URG 플래그가 1로 설정되었을 때만 유효한 의미를 가진다. 긴급 포인터의 값은 시퀀스 번호에 더해져, 긴급 데이터의 마지막 바이트 위치를 나타낸다[7].
긴급 포인터의 주요 목적은 수신 측 TCP에 긴급한 처리가 필요한 데이터가 포함되어 있음을 알리고, 해당 데이터의 정확한 종료 지점을 식별하도록 하는 것이다. 예를 들어, 원격 터미널 세션에서 인터럽트 키(예: Ctrl+C)를 전송하는 경우에 활용될 수 있다. 그러나 현대 대부분의 네트워크 애플리케이션과 운영 체제는 이 메커니즘을 거의 사용하지 않거나, 다른 신호 처리 방식을 선호한다.
긴급 포인터의 해석과 관련하여 역사적으로 두 가지 모델이 존재했다. 하나는 긴급 포인터가 긴급 데이터의 마지막 바이트를 가리킨다는 RFC 793의 원래 정의이며, 다른 하나는 긴급 데이터의 마지막 바이트 다음 바이트를 가리킨다는 이후의 개정된 해석이다. 이 불일치는 호환성 문제를 일으킬 수 있어, 실제 구현과 사용을 제한하는 요인 중 하나가 되었다.
TCP 세그먼트의 데이터 페이로드는 TCP 헤더 뒤에 위치하며, 실제로 애플리케이션 계층에서 교환하려는 사용자 데이터를 담는 부분이다. 이 부분은 선택적이며, 연결 설정이나 종료와 같은 제어용 세그먼트의 경우 데이터 페이로드가 존재하지 않을 수 있다. 데이터 페이로드의 길이는 MSS에 의해 제한되며, 일반적으로 IP 패킷이 MTU를 초과하지 않도록 조정된다.
데이터 페이로드의 크기는 가변적이다. 세그먼트의 전체 길이에서 TCP 헤더 길이를 뺀 값으로 계산된다. 데이터가 없을 경우 시퀀스 번호는 증가하지 않지만, PSH 플래그가 설정된 데이터 페이로드는 수신 측 TCP에게 즉시 상위 계층으로 전달하도록 지시한다. 대용량 데이터를 전송할 때는 여러 개의 TCP 세그먼트로 분할되어 각각의 데이터 페이로드에 나누어 담기게 된다.
용어 | 설명 |
|---|---|
한 번에 전송할 수 있는 데이터 페이로드의 최대 크기[8]. | |
네트워크 경로상에서 전송 가능한 최대 프레임 크기. | |
수신 측에게 버퍼링 없이 데이터를 즉시 응용 프로그램에 넘기도록 하는 제어 비트. |
데이터 페이로드는 TCP의 핵심 서비스인 신뢰성 있는 전송의 대상이 된다. 모든 데이터 페이로드는 시퀀스 번호로 식별되며, 수신 측은 이에 대한 확인 응답을 반드시 보내야 한다. 전송 중 손실이나 오류가 발생하면 해당 세그먼트의 데이터 페이로드는 재전송된다. 따라서 애플리케이션 계층의 프로토콜(예: HTTP, FTP, SMTP) 메시지는 최종적으로 이 데이터 페이로드 영역을 통해 오류 없이 순서대로 전달된다.