
TCP (Transmission Control Protocol)
TCP 헤더구조
TCP는 전송의 신뢰성과 흐름 제어, 혼잡 제어 를 담당하는 프로토콜로, TCP 헤더에는 이 기능들을 위한 여러 가지 값이 담겨 있다. 따라서, TCP 헤더를 보면 TCP의 개괄적인 기능을 쉽게 확인할 수 있다.

이제 그림에 표기된 순서대로 각 필드가 어떤 정보를 담고 있는지 살펴보자.
1. 발신지/목적지 포트 주소

해당 필드들은 각각 2 byte (= 16 bits)를 할당받는다. 이때 출발지와 목적지의 주소를 판별하기 위해서는 IP 주소와 포트 번호가 필요하다.
IP 주소는 네트워크 계층의 IP 헤더에 포함되며, TCP 헤더에는 포트 번호(port) 필드만 존재한다.
2. Sqeunce number

시퀀스 번호는 바이트 단위로 구분되어 순서화되는 번호로, 이를 통해 TCP의 신뢰성 및 흐름제어 기능을 제공한다. 또한 수신자는 쪼개진 세그먼트의 순서를 파악하여 올바른 순서로 데이터를 재조립할 수 있게 된다.
최대 32 bit, 즉 4 byte (2^32) 크기의 송신 데이터에, 순서화된 일련번호를 붙일 수 있다.
송신자가 최초로 데이터를 전송할 때는 이 번호를 랜덤 한 수로 초기화하며 이후 자신이 보낼 데이터의 1 byte 당 시퀀스 번호를 1씩 증가시키며 데이터의 순서를 표현한다. 최대값( 4,294,967,296 )이후에는 다시 0부터 시작한다.
3. Acknoledge Number

예시
※ 송신자가 한번에 전송할 수 있는 데이터 양은 네트워크나 수신자의 상태에 따라 가변적이기 때문에, 그냥 100 bytes로 가정한다.

정리하면, 승인 번호는 다음에 보내줘야 할 데이터의 시작점을 의미한다.
4. 헤더 길이 필드 (Header length, HLEN)

해당 필드는 TCP 세그먼트가 시작하는 위치를 기준으로 데이터의 시작 위치를 나타내므로 TCP 헤더의 크기가 된다.
표기할 땐 32-bits 워드(word) 단위를 사용하는데, 이는 32 bit 시스템에서 1 word = 4 bytes 임을 의미한다. 즉, 해당 필드 값에 4를 곱하면 세그먼트에서 헤더를 제외한 실제 데이터의 시작 위치를 알 수 있다. 예를 들어, 헤더 길이 필드 값이 5라면, 5 * 4 = 20 bytes가 헤더의 길이이며, 데이터는 21번째 byte부터 시작된다는 것이다.
이 필드에 할당된 4 bits로 표현할 수 있는 값의 범위는 0000 ~ 1111, 즉 0 ~ 15 word 이므로 기본적으로 0 ~ 60 bytes의 오프셋까지 표현할 수 있다. 하지만 옵션 필드를 제외한 나머지 필드는 필수로 존재해야 하기 때문에 최소 값은 20 bytes, 즉 5 word로 고정되어 있다.
5. 예약 (Reserved)

미래를 위해 예약된 필드로, 모두 0으로 채워져야 한다.
6. Flags

이건 특히 내용이 많고 다룰 것도 많아서 별도의 소제목으로 옮겨 설명하겠다.
7. Window Size

해당 필드는 한 번에 전송할 수 있는 데이터의 양을 의미하는 값을 담는다. 65535 (2^16) 만큼의 값을 표현할 수 있고, 단위는 바이트이므로, window의 최대 크기는 64 KB라는 말이 된다.
만약 전송하는 데이터의 양이 수신자의 버퍼 용량을 초과하여 수신에 실패한다면 해당 필드 값을 0으로 지정한다. 이 경우, 송신자는 데이터를 전송해선 안된다.
8. Checksum

TCP 세그먼트에 포함되는 프로토콜 헤더와 데이터 모두에 대한 변형 오류를 검출하기 위해 사용한다. IP 프로토콜에서 사용하는 오류 검출 알고리즘을 사용한다.
9. Urgent Pointer (긴급 포인터)

긴급 데이터를 처리하기 위한 필드로, 예약 필드의 URG 플래그 비트가 지정된 경우에만 유효하다. 이 필드를 사용해 송신자는 급히 처리해야 하는 데이터를 전송할 수 있다.
예를 들어, 순서 코드가 2000이고 Urgent Pointer가 100인 패킷을 전송한다면 순서 번호 2000 ~ 2099번의 데이터는 긴급 데이터로 전송되고, 2100번 이후로는 정상 데이터로 전송되는 식이다.
TCP Flags

TCP 헤더에는 현재 세그먼트의 목적과 상태를 나타내는 총 9개의 제어 비트 플래그가 있다. 이 플래그들은 TCP 연결의 설정, 종료, 데이터 전송 중 제어, 그리고 혼잡 통보 등에 사용된다.
각 플래그의 의미는 다음과 같다.
| 필드 | 이름 | 기능 및 의미 |
| SYN | Synchronization | - 연결 설정(3-way handshake) 시작을 알린다. - (SYN=1, ACK=0) : 연결 요청 (첫 번째 패킷) - (SYN=0, ACK=1) : 연결 요청에 대한 응답(두 번째 패킷) |
| ACK | Acknowledgement | - 확인 응답 필드의 유효성을 알린다. - (ACK=1) : 수신자가 성공적으로 데이터를 수신한 것으로, ACK Number 필드에 다음에 기대하는 바이트 순서 번호를 담아 전송한다. |
| FIN | Finish | - 정상적인 연결 종료 요청 - 송신자가 더 이상 보낼 데이터가 없음을 알리며, 연결의 절반을 닫는다. (Half-Close) |
| RST | Reset | - 비정상적인 연결 종료 요청 - 유효하지 않거나 존재하지 않는 포트/연결로 패킷이 도착했거나, 연결을 강제로 끊고 싶을 때 사용한다. |
| PSH | Push | - 수신자에게 버퍼링 없이 즉시 응용 프로그램으로 데이터를 전달하도록 요청한다. - 보통 Telnet 같은 상호작용적 통신이나, 송신 측 애플리케이션이 버퍼를 비워야 할 때 사용된다. |
| URG | Urgent | - 해당 세그먼트에 긴급 데이터가 포함되어 있음을 알린다. - Urgent Pointer 필드가 유효해지며, 이 포인터는 긴급 데이터의 끝을 가리킨다. (긴급 데이터가 우선 처리됨) |
| ECE | ECN-Echo (혼잡 통보 응답) |
- 명시적 혼잡 통보(ECN)와 관련하여 사용된다. - (SYN=1, ECE=1, CWR=1) : ECN 사용을 제안/요청한다. - (SYN=1, ECE=1) : ECN 사용을 수락한다. - (SYN=0, ECE=1) : 네트워크 혼잡이 발생했으니 송신자가 윈도우 크기를 줄여달라는 알림이다. - (CWR=1) : 윈도우 감소 완료 |
| CWR | Congestion Window Reduced |
- ECE 플래그를 받은 송신자가 혼잡 제어 알고리즘에 따라 자신의 윈도우 크기를 줄였음을 수신자에게 알리는 응답 플래그 |
| NS | Nonce Sum | - ECN 메커니즘을 사용하는 동안 발생할 수 있는 악의적인 은폐나 실수로부터 ECN 상태를 보호하기 위해 추가된 플래그 (RFC 3540/3548) |
TCP 연결방식 3-way Handshaking

1. SYN
- 연결을 시작하는 첫 번째 단계로, 클라이언트가 서버로 SYN(Synchronize Sequence Numbers) 패킷을 보낸다.
- SYN 패킷에는 클라이언트가 데이터를 보낼 때 사용할 시퀀스 번호가 포함되어 있다.
2. SYN-ACK
- 서버는 클라이언트의 SYN 요청을 받고, SYN과 ACK(Acknowldege)을 결합한 패킷을 클라이언트에게 보낸다.
3. ACK
- 클라이언트는 서버의 SYN-ACK 패킷을 받고, 서버의 시퀀스 번호를 확인하는 ACK 패킷을 서버에게 보낸다.
- 클라이언트가 서버의 초기 시퀀스 번호를 받았으며, 이제 양방향 통신이 가능해졌음을 의미한다.
TCP 해제방식 4-way Handshaking

1. FIN
- 연결을 종료하고자 하는 호스트(클라이언트 or 서버)는 FIN 플래그가 설정된 패킷을 상대방에게 보낸다.
- 이는 해당 호스트가 더 이상 보낼 데이터가 없음을 의미한다.
2. ACK
- 수신 호스트는 FIN 패킷을 받고, ACK 패킷을 보내 이를 확인한다.
- 이때, 수신 호스트는 아직 전송하지 않은 데이터를 모두 보낼 때까지 연결을 유지할 수 있다.
3. FIN
- 수신 호스트가 모든 데이터를 전송하고 나서, 두 번째 FIN 패킷을 초기에 FIN을 보낸 호스트에게 전송한다.
4. ACK
- 연결을 시작한 호스트가 마지막 FIN 패킷에 대해 ACK을 보낸다.
- 이후, 양쪽 모두 해당 연결을 종료한다.
TCP 재전송과 타임아웃
TCP 재전송은 서버와 클라이언트 간 통신 중 어느 한쪽에 패킷이 도착하지 못할 경우 다시 패킷을 보내는 것을 의미한다. 타임 아웃은 TCP 재전송을 구현하는 방식으로, '타이머가 만료되기 전에 패킷이 도착했는가?'를 기준으로 재전송 여부를 결정하는 것이다.

송신자 패킷 소실
- 송신자가 패킷을 보냈지만 중간에 유실되어 수신 측에 도달하지 못한 경우
- 수신자는 패킷이 도착하지 않았으니 ACK를 보내지 않기 때문에 송신자의 타이머만 만료된다.

ACK 패킷 소실
- 수신자가 송신자의 패킷에 대한 ACK 응답을 보냈지만 송신 측에 도달하지 못한 경우
- 이 때도 송신자의 타이머만 만료된다.

이른 타임아웃(Early Timeout)
- 송신자가 패킷을 보냈고 수신자도 응답으로 ACK을 보냈지만 네트워크 지연으로 인해 송신자의 Timer가 만료된 후 ACK가 도착한 경우.
TCP 재전송 및 시간 관리 (RTO와 RTT)
TCP는 신뢰할 수 있는 데이터 전송을 위해 패킷 손실 시 재전송을 수행하며, 이 과정에서 Timeout 시간을 적절히 결정하는 것이 가장 중요하다.
RTT (Round Trip Time)
송신자가 데이터 패킷을 보낸 시점부터 수신자로부터 해당 패킷에 대한 ACK(확인 응답)을 받을 때까지 걸리는 시간을 의미한다.
네트워크 상황을 반영하는 RTT를 지속적으로 측정하여 재전송 타이머(RTO) 값을 결정하는 데 사용한다.

다만, 재전송 패킷의 ACK와 원래 패킷의 ACK를 구분하기 어렵다. 즉, 수신한 ACK가 처음 보낸 요청에 대한 응답인지, 아니면 Timeout으로 인해 재전송한 요청에 대한 응답인지 확실히 알 수 없다. 이 문제를 Roud Trip Time의 모호성(Ambiguity)이라고 한다.
RTO (Retransmission Timeout)
TCP가 ACK을 기다리는 최대 시간이다. 이 시간 안에 ACK을 받지 못하면 패킷이 손실되었다고 판단하고 해당 패킷을 재전송한다.
최적의 RTO를 결정하는 것이 가장 중요하다. 너무 짧으면 불필요한 재전송이 발생하여 네트워크 혼잡을 유발하고, 너무 길면 실제 패킷 손실 시 복구 시간이 길어져 지연이 심화된다.
Triple-Duplicate ACK
송신자가 동일한 ACK 번호를 세 번 중복하여 수신하는 경우, 패킷 손실로 간주하고 Timeout을 기다리지 않고 즉시 재전송을 시작하는 방법이다.
RTO 타이머가 만료될 때까지 기다릴 필요가 없어 불필요한 시간 지연을 방지하고, 빠른 복구(Fast Recovery) 프로세스를 시작할 수 있다.

UDP (User Datagram Protocol)
UDP 헤더구조
UDP는 TCP보다 훨씬 간결하고 오버헤드가 적은 비연결형(Connectionless) 전송 계층 프로토콜이다.

| 필드 | 설명 |
| Source Port | 데이터그램을 보낸 발신 애플리케이션의 포트 번호 |
| Destination Port | 데이터그램을 받을 목적지 애플리케이션의 포트 번호 |
| Length | UDP 헤더와 캡슐화된 데이터의 총 바이트 길이로, 최솟값은 헤더 자체 크기인 bytes |
| Checksum | 헤더와 데이터의 오류를 검출하는 데 사용됨 |
UDP 통신 방식
UDP는 비연결형 프로토콜로, 데이터 전송 전에 TCP의 3-way/4-way 핸드셰이크 같은 연결 설정 및 종료 과정이 없다.
- 송신: 송신자는 데이터에 UDP 헤더를 붙여 데이터그램을 생성하고 네트워크로 즉시 보낸다.
- 수신: 수신자는 데이터그램을 받아 체크섬 오류 검사만 수행한다.
- 비신뢰성: UDP는 패킷의 손실, 중복, 순서 변경 등에 대해 재전송 요청, 순서 보장, 흐름 제어 같은 신뢰성 기능을 제공하지 않는다. 이러한 신뢰성이 필요하면 애플리케이션 계층에서 직접 구현해야 한다.
체크섬 (Checksum) 비교 및 계산
TCP vs. UDP 체크섬
체크섬은 데이터의 무결성을 확인하는 메커니즘으로, TCP와 UDP 모두 사용하지만 그 역할과 필수 여부에 차이가 있다.
| 구분 | UDP Checksum | TCP Checksum |
| 필수 여부 | IPv4에서는 선택적, IPv6에서 필수 | 모든 사용 환경에서 필수 |
| 목적 | 데이터 오류 탐지 (신뢰성 보장 목적 아님) | 데이터 오류 탐지 (신뢰성 보장의 핵심 요소) |
| 구성 요소 | UDP 헤더, 데이터 + Pseudo 헤더 | TCP 헤더, 데이터 + Pseudo 헤더 |
Pseudo 헤더의 역할
Pseudo 헤더는 실제 네트워크로 전송되는 패킷에는 포함되지 않고, 오직 체크섬 계산의 무결성을 높이기 위해 사용되는 가상의 12바이트 필드다.

| 포함 정보 | 이유 |
| 출발지 / 목적지 IP 주소 | 데이터그램이 올바른 출발지에서 와서 올바른 목적지에 도착했는지 확인한다. |
| 프로토콜 번호 | 수신된 세그먼트가 TCP(6) 또는 UDP(17) 중 올바른 전송 프로토콜에 전달되었는지 확인한다. |
| TCP / UDP 길이 | 길이 정보의 무결성을 확인한다. |
체크섬 계산 방식 (1의 보수 합계)

- 체크섬을 계산할 모든 필드 (Pseudo 헤더, 헤더, 데이터)를 16 bits 단위로 쪼개어 모두 합산한다.
- 합산 과정에서 발생하는 모든 오버플로우 값(캐리, Carry)은 다시 최종 합에 더한다.
- 이 최종 합에 1의 보수를 취한 값이 체크섬 값으로 헤더에 저장된다.
수신자는 이 과정을 역으로 수행하여, 수신한 모든 데이터의 합과 전송된 체크섬 값을 더해 최종 결과가 16bits 모두 1 (0xFFFF)인지 아닌지를 검사하여 오류 유무를 판단한다.
다만, 체크섬은 오류를 탐지하는 기능으로, 데이터 변조로 인한 에러는 100% 검출할 수는 없다.
참고 출처
- https://www.geeksforgeeks.org/computer-networks/calculation-of-tcp-checksum/
'리팩토링 > 1. 네트워킹' 카테고리의 다른 글
| 리팩토링 6주차. OSI 계층별 프로토콜 특징 (2) (1) | 2024.07.22 |
|---|---|
| 리팩토링 5주차. OSI 계층별 프로토콜 특징 (1) (1) | 2024.07.15 |
| 리팩토링 4주차. OSI 계층별 네트워크 장비 특징 (2) | 2024.07.02 |
| 리팩토링 2주차. OSI 7계층 (1) | 2024.06.10 |
| 리팩토링 1주차. 제로 트러스트(Zero Trust)에 대해 (1) | 2024.06.03 |