전송 제어 프로토콜
1. 개요
1. 개요
전송 제어 프로토콜(Transmission Control Protocol, TCP)은 인터넷 프로토콜 스위트(TCP/IP)의 핵심 프로토콜 중 하나로, 인터넷과 같은 패킷 교환 네트워크에서 신뢰성 있는 연결 지향 통신을 제공한다. 인터넷 프로토콜(IP)이 패킷의 주소 지정과 라우팅을 담당하는 반면, TCP는 애플리케이션 간의 논리적 연결을 설정하고 데이터의 순차적이고 오류 없는 전달을 보장하는 역할을 한다.
TCP는 데이터그램 기반의 비연결형 서비스를 제공하는 사용자 데이터그램 프로토콜(UDP)과 대비되는 특징을 가진다. TCP는 전송 전에 3방향 핸드셰이크 과정을 통해 양단 간 연결을 설정하며, 흐름 제어, 혼잡 제어, 재전송 메커니즘을 통해 데이터 손실, 중복, 순서 바뀜 등을 방지한다. 이러한 특성으로 인해 월드 와이드 웹(HTTP), 전자 메일(SMTP, POP3, IMAP), 파일 전송(FTP) 등 데이터의 완전한 전송이 필수적인 대부분의 인터넷 애플리케이션에서 사용된다.
TCP의 기본 동작 모델은 클라이언트-서버 모델에 기반한다. 한쪽 끝의 TCP 소켓이 다른 쪽 끝의 TCP 소켓과 연결되어 바이트 스트림을 송수신한다. 이 프로토콜은 1970년대 빈트 서프와 밥 칸에 의해 처음 설계되었으며, 이후 RFC 793을 비롯한 여러 표준 문서로 공식 정의되고 지속적으로 개선되어 왔다[1].
2. TCP의 주요 특징
2. TCP의 주요 특징
TCP는 인터넷 프로토콜 스위트의 핵심 프로토콜 중 하나로, IP가 제공하는 비연결형, 비신뢰성 패킷 전송 서비스 위에 신뢰성 있는 연결형 서비스를 구축한다. 그 주요 특징은 다음과 같다.
첫째, TCP는 연결 지향성을 가진다. 데이터를 교환하기 전에 송신자와 수신자 사이에 논리적인 연결을 설정하는 과정을 거친다. 이 과정을 3방향 핸드셰이크라고 한다. 연결이 설정되면 양단은 연결 상태를 유지하며 데이터를 주고받는다.
둘째, TCP는 신뢰성 있는 데이터 전송을 보장한다. 이를 위해 시퀀스 번호와 확인 응답 번호를 사용한다. 수신 측은 성공적으로 수신한 데이터에 대해 확인 응답(ACK)을 보내고, 송신 측은 일정 시간 내에 ACK를 받지 못하면 데이터를 재전송한다. 또한 체크섬을 통해 데이터 손상을 검출한다.
셋째, 흐름 제어 기능을 제공한다. 수신자의 처리 능력을 고려하여 송신 속도를 조절한다. 주로 슬라이딩 윈도우 프로토콜과 수신자가 알려주는 윈도우 크기를 사용한다. 이를 통해 빠른 송신자가 느린 수신자를 압도하는 것을 방지한다.
넷째, 혼잡 제어 메커니즘을 구현한다. 네트워크의 혼잡을 감지하고 송신 속도를 조절하여 네트워크의 과부하를 방지한다. 대표적인 알고리즘으로 슬로우 스타트, 혼잡 회피, 빠른 회복 등이 있다.
다섯째, 전이중 통신을 지원한다. 하나의 연결 안에서 양방향으로 데이터를 동시에 전송할 수 있다. 각 방향의 데이터 흐름은 독립적인 시퀀스 번호와 윈도우를 가진다.
2.1. 연결 지향성
2.1. 연결 지향성
TCP는 데이터 전송을 시작하기 전에 송신자와 수신자 사이에 논리적인 연결을 먼저 설정하는 연결 지향 프로토콜이다. 이 과정은 3방향 핸드셰이크로 알려져 있으며, SYN과 ACK 플래그를 사용하여 양측의 통신 준비 상태를 확인한다. 연결이 성립되면, 양단은 데이터를 주고받을 수 있는 상태가 되며, 이 연결은 데이터 교환이 완료될 때까지 유지된다. 이는 비연결형 프로토콜인 UDP와 대비되는 핵심적인 특성이다.
연결 지향성은 데이터의 순서와 신뢰성을 보장하는 기반이 된다. 설정된 연결을 통해 TCP는 모든 데이터 세그먼트에 고유한 시퀀스 번호를 부여하고, 수신 측의 확인 응답을 통해 각 세그먼트의 성공적 수신을 확인한다. 이 메커니즘은 패킷 손실, 중복, 순서 뒤바뀜과 같은 네트워크 문제를 감지하고 복구할 수 있게 한다. 따라서 애플리케이션 계층은 데이터가 순서대로, 오류 없이 전달될 것이라는 신뢰성을 제공받는다.
연결의 수명 주기는 명확하게 관리된다. 통신이 종료되면, FIN 플래그를 사용한 4방향 핸드셰이크 과정을 통해 연결을 정상적으로 해제한다. 이는 양측이 모두 데이터 전송을 완료했음을 서로 알리고, 사용했던 리소스를 해제하기 위한 절차이다. 이러한 체계적인 연결 설정, 유지, 종료 과정은 TCP가 신뢰성 있는 엔드투엔드 통신을 제공하는 데 필수적이다.
2.2. 신뢰성 있는 데이터 전송
2.2. 신뢰성 있는 데이터 전송
TCP는 데이터가 손실되거나 중복되거나 순서가 바뀌지 않고 정확하게 목적지에 도착하도록 보장하는 신뢰성 있는 데이터 전송 서비스를 제공한다. 이는 IP와 같은 하위 계층의 비연결적이고 신뢰할 수 없는 전송 서비스를 보완하는 핵심 기능이다.
신뢰성을 보장하기 위한 주요 메커니즘으로는 시퀀스 번호, 확인 응답(ACK), 그리고 재전송 타이머가 있다. 송신 측은 전송하는 각 데이터 세그먼트에 고유한 시퀀스 번호를 부여한다. 수신 측은 이 세그먼트를 성공적으로 수신하면, 다음에 기대하는 시퀀스 번호를 담은 ACK 패킷을 송신 측으로 보낸다. 송신 측은 ACK를 받지 못한 데이터에 대해 재전송 타이머가 만료되면 해당 데이터를 다시 전송한다. 이 과정을 통해 단일 패킷의 손실도 복구할 수 있다.
데이터의 순서 보장과 중복 제거도 신뢰성의 중요한 요소이다. 수신 측은 시퀀스 번호를 기준으로 도착한 세그먼트들을 올바른 순서로 재조립한다. 네트워크 지연으로 인해 같은 세그먼트가 중복되어 도착할 경우, 수신 측은 시퀀스 번호를 확인하여 중복된 데이터를 버린다. 또한, 체크섬 필드를 사용하여 세그먼트 헤더와 데이터에 오류가 발생했는지 검사한다. 체크섬 검사에 실패한 세그먼트는 자동으로 폐기되어 재전송을 유발한다.
이러한 메커니즘들은 종합적으로 작동하여, 애플리케이션 계층에는 마치 완벽한 전송 경로가 존재하는 것처럼 데이터 스트림을 제공한다. 결과적으로 파일 전송이나 웹 브라우징과 같이 데이터의 정확성이 필수적인 애플리케이션에서 TCP가 널리 사용되는 근간이 된다.
2.3. 흐름 제어
2.3. 흐름 제어
흐름 제어는 전송 제어 프로토콜이 데이터 송신자와 수신자 간의 처리 속도 차이로 인한 문제를 방지하기 위한 핵심 메커니즘이다. 수신자의 버퍼가 가득 차서 도착한 데이터를 처리할 수 없는 상황, 즉 오버플로가 발생하는 것을 막는 것이 주된 목적이다. 이를 통해 수신자는 자신의 현재 처리 능력에 맞춰 송신자에게 데이터 전송 속도를 조절하도록 알릴 수 있다.
흐름 제어의 핵심은 슬라이딩 윈도우 프로토콜과 수신 윈도우 필드이다. 수신자는 TCP 헤더의 '윈도우 크기' 필드를 통해 자신의 가용 버퍼 공간 크기를 바이트 단위로 송신자에게 지속적으로 알린다. 이 값은 확인 응답 패킷에 함께 담겨 전송된다. 송신자는 이 윈도우 크기 값을 기준으로, 수신자의 확인을 기다리지 않고 한꺼번에 보낼 수 있는 데이터의 최대량을 결정한다. 이렇게 허용된 범위 내에서 윈도우는 데이터의 확인 응답이 도착함에 따라 앞으로 '슬라이딩'하며 이동한다.
만약 수신자의 버퍼가 거의 가득 차서 윈도우 크기가 0으로 알려지면, 송신자는 데이터 전송을 중지한다. 수신자가 데이터를 처리하고 버퍼 공간이 생기면, 새로운 윈도우 크기를 담은 확인 응답 패킷 또는 윈도우 업데이트 패킷을 송신자에게 보내 전송을 재개하도록 한다. 이 메커니즘은 상대적으로 처리 속도가 느린 수신자가 빠른 송신자에 의해 압도당하는 것을 방지하여 데이터 손실 없이 효율적인 전송을 가능하게 한다.
2.4. 혼잡 제어
2.4. 혼잡 제어
혼잡 제어는 전송 제어 프로토콜이 네트워크의 과부하를 방지하고 공정한 대역폭 분배를 위해 사용하는 핵심 메커니즘이다. 네트워크 경로 상의 라우터나 스위치와 같은 중간 노드가 처리할 수 있는 양보다 더 많은 데이터가 전송되면 패킷 손실이 발생할 수 있다. TCP의 혼잡 제어는 이러한 상황을 감지하고, 송신 측의 데이터 전송 속도를 동적으로 조절하여 네트워크의 안정성을 유지한다.
혼잡 제어의 기본 원리는 혼잡 창을 통해 구현된다. 혼잡 창은 송신자가 수신자의 수신 능력(수신 창)과 무관하게, 네트워크의 혼잡 상태를 고려하여 한 번에 전송할 수 있는 데이터의 양을 결정하는 변수이다. 초기에는 작은 값으로 시작하여 데이터 전송이 성공적으로 확인응답될 때마다 창 크기를 점진적으로 증가시킨다. 그러나 패킷 손실이 감지되면, 이는 네트워크 혼잡의 신호로 해석되어 혼잡 창 크기를 급격히 줄인다.
주요 혼잡 제어 알고리즘은 다음과 같은 단계를 포함한다.
단계 | 주요 동작 | 목적 |
|---|---|---|
연결 초기 또는 손실 후, 혼잡 창을 지수적으로 증가시킴 | 사용 가능한 네트워크 대역폭을 빠르게 탐색 | |
혼잡 창이 임계값에 도달하면 선형적으로 증가시킴 | 혼잡을 피하면서 대역폭을 효율적으로 활용 | |
중복된 확인 응답을 받으면 손실된 세그먼트를 즉시 재전송함 | 재전송 타이머 만료를 기다리지 않고 손실 복구 | |
빠른 재전송 후, 혼잡 창을 절반으로 줄이고 선형 증가로 전환함 | 패킷 손실 후의 성능 저하를 완화 |
이러한 메커니즘을 통해 TCP는 네트워크 상태에 적응하며, 단일 연결이 전체 링크를 독점하는 것을 방지하고 여러 연결이 공평하게 대역폭을 공유할 수 있게 한다. 현대의 CUBIC TCP나 BBR과 같은 알고리즘은 전통적인 TCP Reno 방식을 개선하여 고대역폭·고지연 네트워크 환경에서 더 나은 성능을 제공한다.
2.5. 전이중 통신
2.5. 전이중 통신
전이중 통신은 통신 채널을 통해 데이터가 양방향으로 동시에 전송될 수 있는 방식을 의미한다. TCP는 이러한 전이중 통신을 지원하여, 한 쌍의 연결된 호스트가 동시에 데이터를 보내고 받을 수 있게 한다. 이는 반이중 통신이나 단방향 통신과 구별되는 중요한 특징이다.
TCP 연결은 두 개의 독립적인 단방향 데이터 스트림으로 구성된다. 각 방향은 고유한 시퀀스 번호 공간과 확인 응답 번호를 사용하여 데이터의 순서와 신뢰성을 관리한다. 따라서 송신자가 데이터를 보내는 동안에도 수신자는 자신의 데이터나 ACK 패킷을 동시에 회신할 수 있다. 이는 전화 통화와 유사하게 양측이 동시에 말을 할 수 있는 모델이다.
이 기능은 흐름 제어와 혼잡 제어 메커니즘이 각 방향에 대해 독립적으로 작동할 수 있도록 설계의 기반이 된다. 예를 들어, 한 방향의 네트워크가 혼잡하더라도 반대 방향의 데이터 흐름은 영향을 받지 않고 계속될 수 있다. 전이중 통신은 대역폭을 효율적으로 활용하고, 지연 시간을 줄여 대화형 애플리케이션의 응답성을 높이는 데 기여한다.
3. TCP 헤더 구조
3. TCP 헤더 구조
TCP 헤더는 TCP 세그먼트의 시작 부분에 위치하며, 통신에 필요한 제어 정보를 담고 있다. 헤더의 기본 길이는 20바이트이지만, 옵션 필드가 포함되면 최대 60바이트까지 확장될 수 있다. 헤더는 여러 필드로 구성되어 연결 지향성, 신뢰성 있는 데이터 전송, 흐름 제어, 혼잡 제어를 구현하는 데 필요한 정보를 제공한다.
헤더의 주요 필드는 다음과 같다.
필드 (비트) | 설명 |
|---|---|
송신 포트 (16) / 수신 포트 (16) | 통신하는 애플리케이션의 포트 번호를 지정한다. |
시퀀스 번호 (32) | 전송하는 데이터 바이트 스트림의 순서를 식별한다. |
확인 응답 번호 (32) | 수신 측이 다음으로 기대하는 시퀀스 번호를 나타낸다. |
데이터 오프셋 (4) | TCP 헤더의 길이를 4바이트 단위로 표시한다. |
예약 (6) | 미래 사용을 위해 예약된 비트로, 일반적으로 0으로 설정된다. |
플래그 비트 (6) | |
윈도우 크기 (16) | |
체크섬 (16) | 헤더와 데이터의 오류를 검출하기 위해 사용된다. |
긴급 포인터 (16) | URG 플래그가 설정되었을 때 긴급 데이터의 위치를 가리킨다. |
옵션 (가변) | 최대 세그먼트 크기 협상, 선택적 확인 응답 사용 등 추가 기능을 제공한다. |
플래그 비트는 연결의 상태를 제어하는 핵심 신호이다. SYN과 FIN은 각각 연결 설정과 종료를, ACK는 확인 응답의 유무를, RST는 연결의 강제 재설정을 나타낸다. 윈도우 크기 필드는 수신 측의 현재 버퍼 여유 공간을 송신 측에 알려, 송신 속도를 조절하는 흐름 제어의 기초가 된다. 옵션 필드는 표준 헤더를 확장하여, 예를 들어 윈도우 스케일링을 통해 65,535바이트 이상의 큰 윈도우를 지원하도록 협상하는 데 사용된다.
3.1. 포트 번호
3.1. 포트 번호
포트 번호는 전송 제어 프로토콜 연결에서 출발지와 목적지 애플리케이션을 식별하는 16비트 논리적 주소이다. IP 주소가 특정 컴퓨터(호스트)를 가리킨다면, 포트 번호는 그 호스트 내에서 실행 중인 특정 프로세스나 서비스를 정확히 지정하는 역할을 한다. 이를 통해 단일 IP 주소를 가진 호스트에서도 웹 서버, 이메일 서버, 파일 전송 서버 등 여러 네트워크 서비스가 동시에 운영될 수 있다.
포트 번호는 0부터 65535까지의 범위를 가지며, 크게 세 가지 범주로 나뉜다.
포트 범위 | 구분 | 설명 | 예시 |
|---|---|---|---|
0 - 1023 | 잘 알려진 포트 (Well-Known Ports) | IANA에 의해 공식 할당된 시스템 서비스용 포트 | |
1024 - 49151 | 등록된 포트 (Registered Ports) | 소프트웨어 회사가 IANA에 등록하여 사용하는 포트 | 3306(MySQL), 3389(원격 데스크톱) |
49152 - 65535 | 동적/사설 포트 (Dynamic/Private Ports) | 클라이언트 측에서 임시로 연결에 사용하는 포트 | 일반적으로 클라이언트의 임시 포트 |
TCP 헤더에는 출발지 포트 번호 필드와 목적지 포트 번호 필드가 각각 존재한다. 서버는 일반적으로 잘 알려진 포트에서 수신 대기(listening)하며, 클라이언트는 연결을 시작할 때 운영 체제로부터 임시로 할당받은 동적 포트를 출발지 포트로 사용한다. 이 쌍(출발지 IP:포트, 목적지 IP:포트)을 통해 하나의 호스트에서 발생하는 수많은 네트워크 연결을 고유하게 구별할 수 있다. 예를 들어, 웹 브라우저로 동시에 여러 웹사이트에 접속하는 경우, 각 탭의 연결은 서로 다른 클라이언트 포트 번호를 사용하여 구분된다.
3.2. 시퀀스 번호와 확인 응답 번호
3.2. 시퀀스 번호와 확인 응답 번호
시퀀스 번호는 전송되는 데이터의 각 옥텟(바이트)에 순차적으로 부여되는 32비트 숫자이다. 연결 설정 과정에서 임의의 초기값(Initial Sequence Number, ISN)으로 시작하여, 전송하는 데이터의 첫 번째 옥텟 번호를 나타낸다. 예를 들어, 시퀀스 번호가 1000이고 데이터 크기가 100바이트라면, 이 세그먼트는 1000번부터 1099번까지의 옥텟을 담고 있다고 식별된다. 이 번호는 데이터의 순서를 정렬하고, 중복된 세그먼트를 식별하며, 신뢰성 있는 전송의 기초를 제공한다.
확인 응답 번호(ACK 번호)는 수신 측이 성공적으로 수신한 데이터의 다음 예상 시퀀스 번호를 의미한다. 이는 누적 확인 응답의 원리를 따른다. 수신자가 확인 응답 번호 1100을 보낸다면, 이는 시퀀스 번호 1099까지의 모든 데이터를 무결하게 수신했으며, 다음으로 1100번 옥텟을 기대한다는 것을 송신자에게 알린다. 확인 응답 번호는 TCP 헤더의 ACK 플래그 비트가 설정되었을 때만 유효하다.
이 두 번호 체계는 재전송 메커니즘의 핵심이다. 송신자는 보낸 데이터에 대한 확인 응답을 일정 시간(재전송 타임아웃, RTO) 내에 받지 못하면, 해당 시퀀스 번호부터 데이터를 다시 전송한다. 또한, 수신자가 예상하지 않은 시퀀스 번호의 세그먼트를 받으면(예: 패킷 손실 또는 순서 바뀜), 마지막으로 정상 수신된 데이터의 시퀀스 번호를 확인 응답 번호로 반복하여 보냄으로써 손실을 알릴 수 있다.
시퀀스 번호 공간은 2^32(약 43억) 크기를 가지며 순환한다. 고속 네트워크 환경에서는 이 번호가 빠르게 소진되어 재사용될 수 있으므로, 이를 안전하게 처리하기 위해 타임스탬프 옵션 등의 메커니즘이 함께 사용된다[2].
3.3. 플래그 비트
3.3. 플래그 비트
TCP 헤더에는 6비트로 구성된 제어 플래그 필드가 존재하며, 각 비트는 특정 통신 상태나 제어 기능을 나타낸다. 이 플래그들은 3방향 핸드셰이크 및 데이터 전송 과정에서 연결의 설정, 유지, 종료를 관리하는 데 핵심적인 역할을 한다.
주요 플래그 비트와 그 기능은 다음과 같다.
플래그 약어 | 플래그 명칭 | 설명 |
|---|---|---|
URG | 긴급 (Urgent) | 긴급 포인터 필드의 값이 유효함을 나타낸다. 이 플래그가 설정되면 수신 측은 해당 데이터를 우선적으로 처리한다. |
ACK | 확인 응답 (Acknowledgment) | 확인 응답 번호 필드의 값이 유효함을 나타낸다. 연결 성립 후 대부분의 세그먼트는 이 플래그가 설정되어 전송된다. |
PSH | 밀어넣기 (Push) | 수신 측에게 버퍼링 없이 이 데이터를 즉시 상위 애플케이션에 전달하도록 요청한다. |
RST | 연결 재설정 (Reset) | 비정상적인 상황으로 인해 연결을 강제로 재설정해야 함을 알린다. |
SYN | 동기화 (Synchronize) | 연결 설정을 요청할 때 사용되며, 시퀀스 번호의 초기 값을 동기화한다. |
FIN | 종료 (Finish) | 송신 측의 데이터 전송이 끝났음을 알리고 연결 종료 절차를 시작한다. |
이 중 SYN과 ACK 플래그는 연결 설정 과정에서, FIN과 ACK 플래그는 연결 종료 과정에서 조합되어 사용된다. RST 플래그는 예기치 못한 연결 요청이나 오류 상황에서 전송되며, URG와 PSH 플래그는 일반적인 데이터 전송 중 특별한 처리가 필요할 때 활용된다. 이러한 플래그들의 조합을 통해 TCP는 상태 기반의 정교한 연결 관리를 가능하게 한다.
3.4. 윈도우 크기
3.4. 윈도우 크기
윈도우 크기 필드는 TCP 헤더의 일부로, 수신 측이 현재 수용할 수 있는 데이터의 양을 바이트 단위로 송신 측에 알리는 역할을 한다. 이 값은 흐름 제어의 핵심 매커니즘으로 작동하여, 빠른 송신자가 느린 수신자를 압도하지 않도록 한다. 수신 측은 자신의 수신 버퍼에 남아 있는 가용 공간을 기반으로 이 값을 동적으로 계산하여 확인 응답 세그먼트에 담아 보낸다.
윈도우 크기의 값은 16비트 필드로 표현되므로, 원래 규격상 최대 크기는 65,535바이트(64KB - 1)로 제한된다. 현대 고대역폭 네트워크에서는 이 크기가 병목 현상을 일으킬 수 있다. 이 제한을 극복하기 위해 TCP 윈도우 스케일링 옵션이 도입되었다. 이 옵션은 핸드셰이크 과정에서 협상되며, 윈도우 크기 값에 스케일 팩터를 적용하여 최대 1GB에 가까운 크기까지 지원할 수 있다.
윈도우 크기는 네트워크의 혼잡 제어 상태를 반영하기도 한다. 혼잡 제어 알고리즘은 네트워크에 패킷이 과도하게 몰리는 것을 방지하기 위해, 실제로 사용 가능한 윈도우 크기를 수신자 공지 윈도우와 혼잡 윈도우 중 더 작은 값으로 결정한다. 이는 효율적인 데이터 전송과 네트워크 안정성을 동시에 보장한다.
4. TCP 연결 관리
4. TCP 연결 관리
TCP 연결 관리는 TCP가 연결 지향 프로토콜로서 통신을 시작하고 종료하는 과정을 체계적으로 관리하는 절차를 말한다. 이 과정은 신뢰성 있는 데이터 전송의 기초를 제공하며, 주로 3방향 핸드셰이크를 통한 연결 설정과 4방향 핸드셰이크를 통한 연결 종료로 구성된다.
연결 설정은 3방향 핸드셰이크로 이루어진다. 먼저, 클라이언트는 서버에게 SYN 플래그가 설정된 패킷을 보낸다. 이 패킷에는 초기 시퀀스 번호가 포함된다. 서버는 이에 응답하여 SYN과 ACK 플래그가 모두 설정된 패킷을 보내며, 이 패킷에는 서버의 초기 시퀀스 번호와 클라이언트의 시퀀스 번호에 대한 확인 응답이 담긴다. 마지막으로 클라이언트가 서버에게 ACK 패킷을 보내면 연결이 성립된다. 이 과정을 통해 양측은 상대방의 초기 시퀀스 번호를 교환하고 통신 준비가 완료되었음을 확인한다.
연결 종료는 일반적으로 4방향 핸드셰이크를 통해 이루어진다. 연결을 종료하려는 측(보통 클라이언트)이 FIN 플래그가 설정된 패킷을 보내면, 수신 측(서버)은 이에 대한 ACK를 보낸다. 이후 서버도 데이터 전송을 마치고 나면 자신의 FIN 패킷을 보낸다. 최종적으로 클라이언트가 이 FIN에 대한 ACK를 보내면 연결이 완전히 종료된다. 연결 종료 과정에서 양측은 보낼 데이터가 모두 전송되었는지 확인하고, 남은 패킷이 네트워크에서 소실되지 않도록 보장하는 시간을 가진다[3].
단계 | 송신자 → 수신자 | 패킷 플래그 | 주요 목적 |
|---|---|---|---|
연결 설정 1 | 클라이언트 → 서버 | SYN | 연결 요청 및 초기 시퀀스 번호 통지 |
연결 설정 2 | 서버 → 클라이언트 | SYN, ACK | 요청 수락 및 서버의 초기 시퀀스 번호 통지 |
연결 설정 3 | 클라이언트 → 서버 | ACK | 연결 확립 확인 |
연결 종료 1 | 종료 시작측 → 상대측 | FIN | 연결 종료 요청 |
연결 종료 2 | 상대측 → 종료 시작측 | ACK | 종료 요청 확인 응답 |
연결 종료 3 | 상대측 → 종료 시작측 | FIN | 상대측의 종료 요청 |
연결 종료 4 | 종료 시작측 → 상대측 | ACK | 최종 확인 응답 및 연결 종료 |
4.1. 3방향 핸드셰이크
4.1. 3방향 핸드셰이크
TCP 연결을 설정하는 과정을 3방향 핸드셰이크라고 부른다. 이 과정은 클라이언트와 서버가 서로의 통신 준비 상태를 확인하고 초기 시퀀스 번호를 교환하여 신뢰성 있는 연결의 기반을 마련한다. 핸드셰이크는 총 세 단계의 패킷 교환으로 이루어진다.
첫 번째 단계에서 연결을 시작하려는 클라이언트는 SYN 플래그 비트가 1로 설정된 패킷을 서버로 보낸다. 이 패킷에는 클라이언트가 임의로 선택한 초기 시퀀스 번호가 포함된다. 두 번째 단계에서 서버는 이 SYN 패킷을 수신하면, SYN과 ACK 플래그를 모두 1로 설정한 응답 패킷을 되돌려보낸다. 이 패킷에는 서버 자신의 초기 시퀀스 번호와, 클라이언트의 시퀀스 번호에 1을 더한 값으로 구성된 확인 응답 번호가 담긴다. 마지막으로, 클라이언트는 서버의 SYN-ACK 패킷을 받고 ACK 플래그가 설정된 확인 응답 패킷을 서버로 보낸다. 이 패킷의 확인 응답 번호는 서버의 시퀀스 번호에 1을 더한 값이다.
이 세 번째 ACK 패킷의 전송이 완료되면, 양측 모두 연결이 성립되었다고 판단하고 데이터 전송 단계로 진입한다. 이 과정을 통해 양측은 상대방이 패킷을 송수신할 준비가 되어 있음을 보장하며, 이후 데이터의 순서와 무결성을 관리하는 데 필수적인 초기 시퀀스 번호를 동기화한다. 3방향 핸드셰이크는 TCP의 연결 지향성과 신뢰성을 실현하는 첫 번째 핵심 절차이다.
4.2. 연결 종료 (4방향 핸드셰이크)
4.2. 연결 종료 (4방향 핸드셰이크)
연결 종료는 3방향 핸드셰이크로 시작된 TCP 연결을 정상적으로 해제하는 과정이다. 이 과정은 총 네 번의 세그먼트 교환으로 이루어지기 때문에 '4방향 핸드셰이크'라고 불린다. 각 방향은 FIN 플래그와 ACK 플래그를 사용하여 양측의 데이터 전송 종료를 협상한다.
연결 종료는 일반적으로 한쪽이 먼저 종료를 요청하는 방식으로 시작된다. 먼저 연결을 종료하려는 호스트(예: 클라이언트)는 TCP 헤더의 플래그 비트 중 FIN 비트를 1로 설정한 세그먼트를 상대방(서버)에게 보낸다. 이는 더 이상 보낼 데이터가 없음을 알리는 것이다. 서버는 이 FIN 세그먼트를 받으면 즉시 ACK로 응답하여 수신을 확인한다. 이 시점에서 클라이언트에서 서버 방향의 데이터 흐름은 종료된다.
그러나 서버 측에도 아직 전송해야 할 데이터가 남아 있을 수 있다. 따라서 서버는 자신의 모든 데이터 전송을 마친 후, 독립적으로 FIN 플래그가 설정된 세그먼트를 클라이언트에게 보낸다. 클라이언트는 이 FIN 세그먼트를 받고 마찬가지로 ACK로 응답한다. 이 ACK를 받은 서버는 연결을 완전히 닫는다. 클라이언트는 일정 시간 대기 상태(TIME_WAIT 상태)를 유지한 후 최종적으로 연결 리소스를 해제한다.
단계 | 송신자 | 수신자 | 세그먼트 플래그 | 설명 |
|---|---|---|---|---|
1 | 클라이언트 | 서버 | FIN | 클라이언트가 연결 종료를 요청 |
2 | 서버 | 클라이언트 | ACK | 서버가 클라이언트의 FIN 요청을 확인 응답 |
3 | 서버 | 클라이언트 | FIN | 서버가 자신의 데이터 전송을 마치고 종료 요청 |
4 | 클라이언트 | 서버 | ACK | 클라이언트가 서버의 FIN 요청을 확인 응답 |
이 과정은 양방향 연결이 독립적으로 닫히도록 보장하여, 한쪽이 종료된 후에도 다른 쪽에서 잔여 데이터를 보낼 수 있게 한다. 마지막 ACK가 유실될 경우를 대비한 TIME_WAIT 상태와 같은 메커니즘은 신뢰성 있는 연결 종료를 완성한다.
5. 신뢰성 보장 메커니즘
5. 신뢰성 보장 메커니즘
TCP는 패킷 손실, 중복, 순서 바뀜 등 인터넷의 비신뢰적 특성에도 불구하고 애플리케이션에 신뢰성 있는 바이트 스트림 전송 서비스를 제공한다. 이를 위해 시퀀스 번호, 확인 응답, 재전송 타이머 등 여러 메커니즘을 조합하여 사용한다.
핵심 메커니즘은 재전송 타이머이다. 송신 측은 세그먼트를 전송할 때마다 재전송 타이머를 시작한다. 수신 측이 해당 데이터에 대한 확인 응답을 제시간에 보내지 않으면 타이머가 만료되고, 송신 측은 해당 데이터를 재전송한다. 타이머의 만료 시간은 왕복 시간을 기반으로 동적으로 계산되며, 네트워크 상태 변화에 적응한다.
손실 감지와 재전송을 촉진하기 위해 중복 ACK 기반의 빠른 재전송 메커니즘이 사용된다. 수신 측이 기대하는 시퀀스 번호보다 큰 번호의 세그먼트를 받으면, 즉 순서가 바뀐 패킷이 도착하면, 마지막으로 정상 수신한 시퀀스 번호에 대한 중복 ACK를 보낸다. 송신 측이 동일한 시퀀스 번호에 대한 중복 ACK를 연속 세 번 받으면, 해당 데이터가 손실되었다고 판단하고 타이머 만료를 기다리지 않고 즉시 재전송한다[4].
효율성을 높이기 위해 선택적 확인 응답 옵션을 사용할 수 있다. 기본적인 TCP는 누적 확인 응답 방식을 사용하므로, 연속되지 않은 여러 세그먼트가 손실되면 첫 번째 손실만 빠르게 감지할 수 있다. SACK 옵션을 사용하면 수신 측이 정상적으로 수신한 데이터 블록의 범위를 송신 측에 알려줄 수 있어, 여러 개의 손실된 세그먼트를 한 번의 왕복 시간 내에 재전송할 수 있다.
5.1. 재전송 타이머
5.1. 재전송 타이머
재전송 타이머는 TCP가 신뢰성 있는 데이터 전송을 보장하기 위한 핵심 메커니즘이다. 데이터 세그먼트를 전송한 후, TCP는 해당 세그먼트에 대한 확인 응답(ACK)을 기다리며 타이머를 시작한다. 만약 설정된 시간 내에 ACK가 도착하지 않으면, TCP는 해당 데이터가 손실되었다고 판단하고 세그먼트를 재전송한다.
이 타이머의 시간 간격을 결정하는 것은 중요한 과제이다. 너무 짧으면 불필요한 재전송이 발생하여 네트워크에 부하를 주고, 너무 길면 손실 복구에 걸리는 시간이 길어져 응용 프로그램의 성능이 저하된다. 따라서 TCP는 네트워크의 왕복 시간을 지속적으로 측정하여 동적으로 재전송 시간을 조정한다. 이 측정된 왕복 시간을 바탕으로 계산된 재전송 시간 초과(RTO) 값이 타이머의 기준이 된다.
재전송이 발생하면, TCP는 혼잡이 발생했다고 간주하고 혼잡 제어 알고리즘을 동작시킨다. 일반적으로 혼잡 윈도우 크기를 크게 줄이고 재전송 타이머의 시간을 지수적으로 증가시킨다[5]. 이는 네트워크의 부하를 빠르게 완화시키기 위한 조치이다. 이후 새로운 ACK가 수신되면 네트워크 상태가 개선된 것으로 보고, 혼잡 윈도우를 다시 증가시키기 시작한다.
5.2. 중복 ACK와 빠른 재전송
5.2. 중복 ACK와 빠른 재전송
중복 ACK는 수신자가 같은 시퀀스 번호를 가진 확인 응답 패킷을 연속적으로 세 번 이상 보낼 때 발생한다. 이는 수신자가 예상한 순서와 다른 시퀀스 번호의 패킷을 받았음을 의미한다. 예를 들어, 수신자가 시퀀스 번호 1000의 패킷을 기다리고 있는데, 시퀀스 번호 2000의 패킷이 먼저 도착하면, 수신자는 여전히 1000번 패킷을 기다리므로 마지막으로 정상 수신한 패킷(예: 시퀀스 번호 999)에 대한 확인 응답을 다시 보낸다. 이것이 중복 ACK이다.
빠른 재전송 메커니즘은 이러한 중복 ACK를 패킷 손실의 강력한 지표로 활용한다. TCP 표준에서는 송신자가 동일한 ACK 번호를 가진 세 개의 중복 ACK를 연속으로 수신하면, 해당 ACK 번호 다음의 데이터 패킷이 손실되었다고 판단하고 재전송 타이머가 만료되기를 기다리지 않고 즉시 해당 패킷을 재전송한다. 이는 지연을 크게 줄여준다.
빠른 재전송 이후, TCP는 일반적으로 혼잡 제어 알고리즘의 빠른 회복 단계로 진입한다. 이 단계에서는 세 개의 중복 ACK가 네트워크 혼잡은 있지만 심각한 수준은 아니라는 신호로 해석되어, 혼잡 윈도우 크기를 급격히 줄이지 않고 절반으로 감소시킨 후 선형적으로 증가시킨다. 이는 슬로우 스타트 단계를 건너뛰고 기존의 혼잡 회피 상태로 빠르게 복귀하여 전송 효율을 유지하는 데 도움을 준다.
5.3. 선택적 확인 응답 (SACK)
5.3. 선택적 확인 응답 (SACK)
선택적 확인 응답은 TCP가 제공하는 신뢰성 있는 데이터 전송 기능을 향상시키는 옵션 메커니즘이다. 기본적인 TCP 확인 응답 방식은 누적 확인 응답을 사용하여, 수신자가 특정 시퀀스 번호까지의 모든 데이터를 성공적으로 수신했음을 알린다. 이 방식은 중간에 손실된 세그먼트가 있을 경우, 그 이후에 도착한 모든 올바른 데이터에 대한 확인 응답도 지연시키는 문제가 있다. SACK은 이 문제를 해결하기 위해, 수신자가 실제로 수신한 데이터 블록의 범위를 송신자에게 추가적으로 알려주어, 손실된 부분만 선택적으로 재전송할 수 있게 한다.
SACK의 동작은 TCP 헤더의 옵션 필드를 통해 이루어진다. 연결 설정 단계인 3방향 핸드셰이크 과정에서 양측 호스트는 SACK-Permitted 옵션을 교환하여 이 기능을 사용할 수 있음을 협상한다. 이후 데이터 전송 중에 수신 측은 SACK 옵션을 포함한 ACK 세그먼트를 보낼 수 있다. 이 옵션 필드에는 수신자가 최근에 성공적으로 수신한 비연속적인 데이터 블록의 시작과 끝 시퀀스 번호가 포함된다. 일반적으로 최대 3개의 SACK 블록 정보를 담아 보낼 수 있다[6].
이 메커니즘은 특히 여러 개의 패킷 손실이 발생한 환경에서 재전송 효율을 크게 높인다. 예를 들어, 송신자가 1번부터 10번까지 10개의 세그먼트를 보냈을 때, 3번과 7번 세그먼트만 손실되었다고 가정한다. 기본적인 누적 ACK 방식을 사용하면 수신자는 3번이 손실되었으므로 2번까지의 수신만을 반복적으로 ACK하게 된다. 그러나 SACK을 사용하면, 수신자는 "4번부터 6번까지", "8번부터 10번까지"의 데이터는 정상 수신되었다는 별도의 블록 정보를 ACK와 함께 보낸다. 송신자는 이 정보를 바탕으로 손실된 3번과 7번 세그먼트만을 정확히 재전송할 수 있다.
SACK은 네트워크의 이용 효율을 개선하고 불필요한 재전송을 줄여 전체 처리량을 향상시킨다. 이는 빠른 재전송 메커니즘과 함께 동작할 때 그 효과가 더욱 두드러진다. 현대의 대부분의 TCP 구현체는 표준적으로 SACK 옵션을 지원한다.
6. TCP 혼잡 제어 알고리즘
6. TCP 혼잡 제어 알고리즘
TCP 혼잡 제어는 네트워크의 혼잡을 감지하고 데이터 전송 속도를 조절하여 네트워크 붕괴를 방지하는 핵심 메커니즘이다. 초기 TCP는 재전송 타이머만을 사용했으나, 1980년대 후반 밴 자콥슨이 제안한 알고리즘을 기반으로 한 표준 방식이 발전했다. 이 알고리즘은 크게 슬로우 스타트, 혼잡 회피, 빠른 재전송, 빠른 회복의 네 가지 주요 단계로 구성된다.
슬로우 스타트 단계에서는 연결 초기에 혼잡 윈도우 크기를 1개의 세그먼트로 시작하여 매 ACK 확인 응답마다 윈도우 크기를 지수적으로 증가시킨다. 이는 네트워크의 수용 가능한 대역폭을 빠르게 탐색하는 과정이다. 혼잡 윈도우가 임계값에 도달하면 혼잡 회피 단계로 진입한다. 이 단계에서는 ACK마다 윈도우 크기를 선형적으로 1씩만 증가시켜 혼잡을 유발할 위험을 줄인다.
패킷 손실이 발생하면, TCP는 이를 네트워크 혼잡의 신호로 간주한다. 세 개의 중복 ACK가 수신되면 빠른 재전송이 트리거되어 손실된 세그먼트를 타임아웃을 기다리지 않고 즉시 재전송한다. 이후 빠른 회복 단계로 들어가 혼잡 윈도우를 반으로 줄이고, 중복 ACK를 수신할 때마다 윈도우를 약간 증가시켜 성능 저하를 완화한다. 타임아웃에 의한 패킷 손실은 더 심각한 혼잡으로 판단되어 슬로우 스타트 단계부터 다시 시작한다.
알고리즘 | 주요 특징 | 혼잡 윈도우 조작 방식 |
|---|---|---|
TCP Tahoe | 초기 구현체, 빠른 회복 미포함 | 손실 시 윈도우를 1로 리셋 |
TCP Reno | 빠른 회복 도입 | 중복 ACK 시 윈도우를 반으로 줄이고 선형 증가 |
TCP NewReno | 부분적 ACK 문제 해결 | 한 RTT 내 여러 패킷 손실 처리 개선 |
CUBIC TCP | 현대 리눅스 기본 알고리즘 | 윈도우 증가를 3차 함수에 기반하여 시간에 따라 결정 |
현대의 CUBIC TCP와 같은 알고리즘은 대역폭과 지연의 곱이 큰 네트워크에서 더 공정하고 효율적인 대역폭 사용을 목표로 한다. 또한 BBR(Bottleneck Bandwidth and Round-trip propagation time)은 패킷 손실을 혼잡 신호로 사용하지 않고, 실제 대역폭과 지연 시간을 모델링하여 전송 속도를 결정하는 새로운 접근법을 제시했다.
6.1. 슬로우 스타트
6.1. 슬로우 스타트
슬로우 스타트는 TCP 혼잡 제어의 핵심 알고리즘 중 하나로, 연결 초기에 네트워크의 수용 가능한 대역폭을 탐색하기 위해 전송 속도를 점진적으로 증가시키는 메커니즘이다. 이 알고리즘은 송신자가 네트워크의 혼잡 상태를 모르는 상황에서 갑작스럽게 많은 데이터를 보내 혼잡을 유발하는 것을 방지하는 데 목적이 있다.
슬로우 스타트는 혼잡 윈도우 크기를 1개의 MSS로 시작하여, 전송한 각 세그먼트에 대한 확인 응답을 정상적으로 수신할 때마다 혼잡 윈도우 크기를 지수 함수적으로 증가시킨다. 구체적으로, 매 RTT마다 혼잡 윈도우 크기가 두 배가 된다. 이는 초기에는 느리게 시작하지만, 성공적인 전송이 이어질수록 윈도우 크기가 급격히 커져 사용 가능한 대역폭을 빠르게 활용할 수 있게 한다.
슬로우 스타트 과정은 다음과 같은 두 가지 조건 중 하나에 도달하면 종료된다.
1. 혼잡 발생: 패킷 손실이 감지되면, 이는 네트워크 혼잡의 신호로 간주된다. 이때 혼잡 회피 단계로 전환된다.
2. 슬로우 스타트 임계값 도달: 사전에 설정된 슬로우 스타트 임계값에 혼잡 윈도우 크기가 도달하면, 지수적 성장을 멈추고 선형적으로 윈도우를 증가시키는 혼잡 회피 단계로 진입한다.
슬로우 스타트는 네트워크 상태에 대한 사전 지식 없이도 효율적으로 대역폭을 활용할 수 있게 하지만, 고대역폭·고지연 네트워크에서는 사용 가능한 대역폭까지 도달하는 데 많은 RTT가 소요될 수 있다는 단점이 있다. 이러한 문제를 완화하기 위해 TCP 윈도우 스케일링과 같은 확장 옵션이 함께 사용되기도 한다.
6.2. 혼잡 회피
6.2. 혼잡 회피
혼잡 회피는 TCP 혼잡 제어 알고리즘의 두 번째 단계로, 슬로우 스타트 단계를 통해 혼잡 윈도우가 혼잡 임계값에 도달한 후 시작된다. 이 단계에서는 네트워크가 포화 상태에 근접했다고 판단하고, 혼잡 윈도우를 더욱 신중하게 증가시켜 패킷 손실을 사전에 방지하는 것을 목표로 한다.
슬로우 스타트 단계에서는 혼잡 윈도우가 지수적으로 증가했지만, 혼잡 회피 단계에서는 선형 증가 방식을 채택한다. 일반적으로 매 왕복 시간 동안 하나의 성공적인 확인 응답을 받을 때마다 혼잡 윈도우 크기를 1 세그먼트만큼 증가시킨다. 이는 네트워크 리소스를 공정하게 공유하고, 갑작스러운 트래픽 증가로 인한 혼잡을 완화하기 위한 보수적인 접근법이다.
혼잡 회피 상태에서 패킷 손실이 발생하면, 이는 네트워크 혼잡이 발생했음을 명확히 나타내는 신호로 해석된다. 손실이 감지되면 혼잡 임계값은 현재 혼잡 윈도우 크기의 절반으로 설정되고, 혼잡 윈도우는 다시 1 세그먼트(또는 새로운 표준에서는 혼잡 임계값 크기)로 줄어든 후 슬로우 스타트 단계부터 재개된다. 이 과정을 통해 TCP는 네트워크의 수용 능력을 지속적으로 탐색하고 조정한다.
초기 TCP Tahoe와 TCP Reno 알고리즘은 혼잡 회피를 구현한 대표적인 예이다. 이들의 핵심 원칙은 "가법 증가 승법 감소"로 요약된다. 즉, 혼잡이 없을 때는 윈도우를 서서히 증가시키고(가법 증가), 혼잡이 감지되면 윈도우를 급격히 줄이는(승법 감소) 방식이다. 이 원리는 네트워크의 안정성과 효율성을 유지하는 데 기여한다.
6.3. 빠른 회복
6.3. 빠른 회복
빠른 회복은 TCP 혼잡 제어 알고리즘의 한 단계로, 패킷 손실이 발생했을 때 혼잡 윈도우 크기를 급격히 줄이지 않고 더 빠르게 네트워크의 이용 가능한 대역폭을 회복하기 위해 설계된 메커니즘이다. 이 알고리즘은 빠른 재전송 단계 이후에 활성화되며, TCP Reno와 TCP NewReno에서 핵심적인 역할을 한다.
빠른 회복의 핵심 동작은 중복 ACK를 통한 패킷 손실 감지 후, 혼잡 윈도우 크기를 반으로 줄이는 대신, 손실된 패킷 하나당 윈도우 크기를 1 MSS(Maximum Segment Size)씩 증가시키는 것이다. 구체적인 절차는 다음과 같다.
1. 세 개의 중복 ACK가 수신되면, 슬로우 스타트 임계값(ssthresh)을 현재 혼잡 윈도우 크기의 절반으로 설정한다.
2. 혼잡 윈도우 크기도 ssthresh + 3 MSS로 조정한다(3개의 중복 ACK는 3개의 패킷이 성공적으로 수신되었음을 의미하므로).
3. 이후 중복 ACK가 도착할 때마다 혼잡 윈도우 크기를 1 MSS씩 증가시켜, 손실된 패킷이 재전송되어 수신될 때까지 윈도우를 확장한다.
4. 손실된 패킷에 대한 새로운 확인 응답 번호를 담은 ACK가 도착하면, 혼잡 윈도우 크기를 ssthresh 값으로 설정하고 혼잡 회피 단계로 진입한다.
이 방식은 TCP Tahoe가 중복 ACK 발생 시 무조건 혼잡 윈도우를 1 MSS로 줄이고 슬로우 스타트를 재개하는 것에 비해 효율적이다. 빠른 회복은 단일 패킷 손실을 임시적인 혼잡으로 간주하고, 네트워크가 아직 포화 상태가 아니라는 신호(중복 ACK가 계속 들어온다는 것은 데이터 흐름이 여전히 있다는 뜻)를 활용하여 전송 속도를 더 빠르게 회복시킨다. 결과적으로 처리량 저하를 완화하고 전체적인 TCP 성능을 향상시킨다.
6.4. CUBIC TCP 등 현대 알고리즘
6.4. CUBIC TCP 등 현대 알고리즘
CUBIC TCP는 TCP 혼잡 제어 알고리즘의 하나로, BIC TCP의 복잡성을 줄이고 현대 고대역폭·지연 곱 네트워크 환경에 더 잘 적응하도록 설계되었다. 이 알고리즘은 리눅스 커널의 기본 TCP 혼잡 제어 알고리즘으로 널리 채택되었다. CUBIC의 핵심 아이디어는 윈도우 크기를 시간의 3차 함수(큐빅 함수)를 사용하여 증가시키는 것이다. 이 함수는 마지막으로 패킷 손실이 발생한 시점을 기준으로 시간의 3제곱에 비례하여 혼잡 윈도우를 증가시킨다. 이 방식은 대역폭을 빠르게 활용하면서도 RTT(왕복 시간)에 덜 민감하게 반응하도록 한다.
CUBIC의 동작은 크게 세 가지 영역으로 나뉜다. 첫 번째는 혼잡 회피 영역으로, 손실 이벤트 이후 윈도우 크기가 급격히 감소한 후, 3차 함수 곡선을 따라 완만하게 증가하다가 손실 이전의 윈도우 크기(W_max)에 도달하기 전까지의 단계이다. 두 번째는 평탄 영역으로, 윈도우 크기가 W_max 근처에 도달하면 증가 속도를 매우 느리게 하여 네트워크를 안정화시킨다. 세 번째는 합리적 영역으로, W_max를 넘어서면 다시 3차 함수에 따라 증가하지만, 이전보다 더 신중하게 대역폭을 탐색한다. 이 곡선 기반의 접근 방식은 RTT 공정성을 향상시키는 데 기여한다. 즉, RTT가 다른 여러 TCP 흐름이 동일한 링크를 공유할 때, TCP Reno 같은 기존 알고리즘보다 더 공정하게 대역폭을 나누어 갖는 경향이 있다.
CUBIC 이후에도 다양한 현대 혼잡 제어 알고리즘이 등장했다. BBR(Bottleneck Bandwidth and Round-trip propagation time)은 구글에서 개발한 알고리즘으로, 패킷 손실을 혼잡의 주요 지표로 보지 않는다. 대신 실제 네트워크 경로의 대역폭과 전파 지연을 직접 측정하여 최적의 송신 속도를 모델링한다. 이는 패킷 손실 없이도 발생하는 버퍼블로트 문제를 완화하는 데 효과적이다. 또 다른 예로 BBR v2와 같은 후속 연구는 ECN(명시적 혼잡 알림)을 통합하여 더 나은 성능을 추구한다.
다음은 주요 현대 TCP 혼잡 제어 알고리즘의 특징을 비교한 표이다.
알고리즘 | 주요 특징 | 개발/주요 사용처 |
|---|---|---|
윈도우 크기를 시간의 3차 함수로 제어. RTT 공정성 향상. | 리눅스 기본 알고리즘 | |
대역폭과 지연 시간을 직접 측정하여 송신률 결정. 버퍼블로트 완화. | 구글 | |
BBR v2 | 구글 (연구/개발 중) | |
지연을 혼잡의 지표로 사용. | ||
대기 지연과 손실 기반 제어를 결합. | 마이크로소프트 윈도우 |
이러한 현대 알고리즘들은 전통적인 손실 기반 혼잡 제어의 한계를 극복하고, 무선 네트워크, 데이터센터, 초고속 광대역 네트워크 등 다양한 새로운 환경에서 TCP의 성능과 효율성을 지속적으로 개선하고 있다.
7. TCP 성능 최적화
7. TCP 성능 최적화
TCP 성능을 향상시키기 위해 여러 최적화 기법이 개발되었다. 이 기법들은 네트워크 효율성을 높이고 불필요한 지연을 줄이는 데 목적을 두었다.
네글 알고리즘은 작은 크기의 데이터 패킷이 빈번하게 전송되는 것을 방지한다. 이 알고리즘은 응용 프로그램에서 보내는 작은 데이터 조각들을 버퍼에 모아 하나의 완전한 TCP 세그먼트로 합친 후 전송한다. 단, 이전에 보낸 데이터에 대한 확인 응답이 도착하거나 모은 데이터가 최대 세그먼트 크기에 도달하면 즉시 전송한다. 이는 네트워크 오버헤드를 줄이지만, 실시간 상호작용이 필요한 애플리케이션에서는 지연을 유발할 수 있다. 지연 ACK는 수신 측의 효율성을 높인다. 수신자는 데이터 세그먼트를 받았을 때 즉시 ACK를 보내지 않고 짧은 시간(보통 200ms 이내) 대기한다. 이 대기 시간 동안에 응용 계층에서 보낼 데이터가 생기면, 그 데이터와 ACK를 하나의 패킷에 담아 함께 회신할 수 있다. 이렇게 하면 네트워크 트래픽을 절반으로 줄일 수 있다.
TCP 윈도우 스케일링은 고대역폭·고지연 네트워크 환경에서의 성능 한계를 해결한다. 표준 TCP 헤더의 윈도우 크기 필드는 16비트로, 최대 65,535바이트까지만 표현할 수 있다. 이는 광역 네트워크에서 대역폭-지연 곱을 충족시키기에 부족할 수 있다. 윈도우 스케일링 옵션은 연결 설정 단계에서 협상되며, 윈도우 크기 값을 왼쪽으로 시프트할 스케일 팩터를 정의한다. 이를 통해 윈도우 크기를 최대 1기가바이트 이상으로 확장할 수 있어, 하나의 TCP 연결이 네트워크 경로의 전체 용량을 효율적으로 활용할 수 있게 한다.
최적화 기법 | 적용 위치 | 주요 목적 | 잠재적 단점 |
|---|---|---|---|
송신 측 | 작은 패킷의 빈번한 전송 방지 (네트워크 오버헤드 감소) | 작은 데이터 전송 시 인위적 지연 발생 | |
수신 측 | ACK 패킷 수 줄이기 (네트워크 트래픽 감소) | 송신 측의 재전송 타임아웃을 유발할 수 있음 | |
송신/수신 측 | 고대역폭·고지연 네트워크에서의 처리량 향상 | 연결 초기 협상이 필요하며, 양단이 지원해야 함 |
7.1. Nagle 알고리즘
7.1. Nagle 알고리즘
Nagle 알고리즘은 네트워크 효율성을 높이기 위해 TCP에서 사용하는 알고리즘이다. 이 알고리즘은 작은 크기의 데이터 패킷이 과도하게 생성되는 현상, 즉 '작은 패킷 문제'를 완화하기 위해 고안되었다. 작은 패킷은 실제 데이터보다 헤더 정보의 비중이 커져 네트워크 대역폭을 비효율적으로 사용하고, 라우터의 처리 부하를 증가시킨다.
알고리즘의 핵심 원리는 아직 확인 응답을 받지 못한 미확인 데이터가 네트워크에 존재하는 동안, 새로 생성된 작은 데이터의 전송을 지연시키는 것이다. 구체적으로, 송신 측은 보낸 데이터에 대한 ACK를 받기 전까지 추가로 생성된 작은 데이터를 버퍼에 모아둔다. 이렇게 모인 데이터는 하나의 큰 세그먼트로 합쳐져 전송되거나, 기존에 보낸 데이터에 대한 ACK가 도착하면 즉시 전송된다.
이 알고리즘은 대화형 애플리케이션(예: 텔넷)이나 작은 메시지를 빈번히 보내는 경우 네트워크 효율성을 크게 향상시킨다. 그러나 데이터 전송 지연을 유발할 수 있어 실시간 응용 프로그램이나 저지연이 중요한 환경에서는 부적합할 수 있다. 이러한 경우, 애플리케이션은 TCP_NODELAY 소켓 옵션을 설정하여 Nagle 알고리즘을 비활성화하기도 한다.
장점 | 단점 |
|---|---|
네트워크 효율성 향상 | 전송 지연 증가 |
작은 패킷 수 감소 | 실시간 통신에 부적합 |
네트워크 혼잡 감소 | 버퍼링으로 인한 메모리 사용 |
Nagle 알고리즘은 기본적으로 대부분의 TCP 구현체에서 활성화되어 있지만, 애플리케이션의 특성에 따라 적절히 활성화하거나 비활성화하는 것이 중요하다.
7.2. 지연 ACK
7.2. 지연 ACK
지연 ACK는 TCP가 ACK 패킷의 전송을 지연시켜 네트워크 효율성을 높이는 메커니즘이다. 기본적으로 수신 측은 데이터를 성공적으로 받을 때마다 즉시 ACK를 보내야 하지만, 이 방식은 작은 크기의 ACK 패킷이 빈번히 전송되어 네트워크 부하를 증가시킬 수 있다. 지연 ACK는 이를 완화하기 위해 ACK 전송을 최대 500밀리초까지 지연시키거나, 다음에 전송할 데이터가 있을 경우 그 데이터와 함께 ACK를 '편승'시켜 보내는 방식을 사용한다.
이 메커니즘의 주요 동작 원리는 다음과 같다. 수신 측은 데이터 세그먼트를 받으면 즉시 ACK를 보내지 않고 짧은 타이머를 시작한다. 타이머가 만료되기 전에 애플리케이션 계층에서 보낼 데이터가 생기면, 그 데이터와 함께 ACK를 담아 한 번에 전송한다. 또한, 연속해서 두 개의 데이터 세그먼트를 받았을 때는 첫 번째 세그먼트에 대한 ACK를 지연하지 않고 즉시 보내어 송신 측의 재전송 타이머가 불필요하게 동작하는 것을 방지한다.
지연 ACK는 네트워크 트래픽을 줄이고 효율성을 높이는 장점이 있지만, 특정 상황에서는 성능에 부정적인 영향을 미칠 수 있다. 예를 들어, 전이중 통신이 활발하지 않은 단방향 트래픽이 주를 이루는 경우, ACK가 지연되어 송신 측의 슬로우 스타트 혼잡 제어 단계에서 윈도우 크기 증가가 지체될 수 있다. 또한, 대화형 애플리케이션에서는 응답 시간이 저하될 우려가 있다. 이러한 이유로 일부 운영체제에서는 지연 ACK의 사용 여부나 지연 시간을 조절할 수 있는 설정을 제공한다.
7.3. TCP 윈도우 스케일링
7.3. TCP 윈도우 스케일링
TCP의 기본 윈도우 크기 필드는 16비트로, 최대 65,535바이트(약 64KB)의 값을 표현할 수 있다. 이는 초기 네트워크 환경에서는 충분했으나, 고대역폭·고지연(장거리) 네트워크에서 대역폭 지연 곱이 커지면 성능 병목 현상을 일으키는 주요 원인이 되었다.
TCP 윈도우 스케일링은 TCP 옵션 필드를 사용하여 이 한계를 극복한다. 연결 설정 단계인 3방향 핸드셰이크 과정에서 양측 호스트가 '윈도우 스케일 옵션'을 교환하며, 이를 통해 기존 16비트 윈도우 값을 왼쪽으로 시프트할 스케일 팩터(shift count)를 협상한다. 예를 들어, 스케일 팩터가 3으로 협상되면, 실제 사용 가능한 수신 윈도우 크기는 헤더의 윈도우 필드 값에 2³(8)을 곱한 값이 된다[7]. 이를 통해 이론상 최대 1,073,725,440바이트(약 1GB)까지 윈도우 크기를 확장할 수 있다.
이 확장은 장거리 고속 네트워크에서 대역폭 지연 곱을 충분히 커버하여 링크 활용률을 높이는 데 필수적이다. 윈도우 스케일링이 적용되지 않으면, 수신자가 보낸 확인 응답을 송신자가 받기 전에 이미 허용된 윈도우 크기만큼의 데이터를 모두 보내게 되어 송신이 멈추는 현상이 빈번히 발생한다. 대부분의 현대 운영체제는 이 기능을 기본적으로 지원한다.
8. TCP 변형 및 확장
8. TCP 변형 및 확장
TCP는 기본 설계 이후 네트워크 환경의 변화와 다양한 애플리케이션 요구사항을 충족시키기 위해 여러 변형과 확장이 개발되었다. 초기의 TCP Tahoe와 TCP Reno는 혼잡 제어의 기본 골격을 마련했으며, 이후 TCP NewReno는 부분적인 ACK 손실 상황에서의 성능을 개선했다. 현대의 고속 네트워크를 위해 TCP CUBIC이 개발되어 대역폭 지연 곱이 큰 환경에서 더 공정하고 효율적으로 동작하도록 했다. 구글은 버퍼블로트 문제를 해결하고 예측 가능한 성능을 제공하기 위해 대역폭과 지연 시간을 직접 측정하는 TCP BBR 알고리즘을 제안했다.
다중 경로를 활용하는 확장도 등장했다. MPTCP(다중 경로 TCP)는 단일 연결에서 여러 네트워크 인터페이스(예: Wi-Fi와 셀룰러)를 동시에 사용할 수 있게 하여 대역폭을 집계하고 한 경로가 끊어져도 연결을 유지하는 견고성을 제공한다. 실시간 미디어 전송을 위해 설계된 TCP-Friendly Rate Control(TFRC)은 UDP 기반의 실시간 전송 프로토콜(RTP)과의 공정한 공존을 목표로 한다. 또한, 데이터 센터 네트워크와 같은 특수 환경을 위해 낮은 지연과 높은 처리량을 동시에 추구하는 데이터 센터 TCP(DCTCP)와 같은 변형도 존재한다.
프로토콜 변형 | 주요 목적/특징 | 적용 환경 예시 |
|---|---|---|
빠른 회복 단계에서 여러 세그먼트 손실 복구 개선 | 일반적인 인터넷 | |
고속 장거리 네트워크에서의 공정성과 확장성 확보 | 광역 네트워크 | |
구글 내부 및 클라우드 서비스 | ||
다중 경로를 통한 대역폭 집계 및 연결 견고성 향상 | 모바일 장치(Wi-Fi/5G 병행) | |
데이터 센터 내 짧은 지연과 높은 처리량 보장 | 데이터 센터 네트워크 |
이러한 변형과 확장은 표준 TCP의 핵심 원칙인 신뢰성과 혼잡 제어를 유지하면서, 특정 성능 메트릭(처리량, 지연, 공정성)을 극대화하거나 새로운 네트워크 기능을 추가하는 방향으로 발전하고 있다.
8.1. TCP Reno, NewReno
8.1. TCP Reno, NewReno
TCP Reno는 TCP Tahoe의 후속 버전으로, 빠른 회복 알고리즘을 도입하여 성능을 개선한 혼잡 제어 알고리즘이다. TCP Tahoe는 혼잡 윈도우를 1로 줄이고 슬로우 스타트 단계부터 다시 시작하는 방식이었으나, Reno는 세 개의 중복 ACK를 받으면 혼잡 윈도우를 절반으로 줄이고 혼잡 회피 단계로 바로 진입하는 빠른 회복을 적용한다. 이로 인해 패킷 손실이 발생해도 연결이 완전히 정지되는 시간을 줄여 전반적인 처리량을 향상시켰다.
그러나 TCP Reno는 한 번의 혼잡 이벤트에서 여러 패킷이 손실되는 경우 성능 저하가 발생하는 문제점을 가지고 있었다. 빠른 회복 상태에서 손실된 각 패킷마다 하나의 재전송 타이머가 만료되어야만 복구가 가능했기 때문에, 여러 패킷이 손실되면 처리량이 급격히 떨어질 수 있었다.
이러한 한계를 극복하기 위해 개발된 것이 TCP NewReno이다. NewReno는 Reno의 빠른 회복 알고리즘을 수정하여 부분적인 ACK를 처리하는 방식을 개선했다. 핵심은 '부분적인 ACK'를 받았을 때, 아직 전송되지 않은 가장 오래된 패킷을 즉시 재전송하고 빠른 회복 상태를 유지하는 것이다. 이를 통해 한 번의 RTT 내에 여러 개의 패킷 손실을 복구할 수 있게 되어, Reno보다 더 나은 성능을 보인다.
알고리즘 | 주요 개선점 | 한계 |
|---|---|---|
빠른 회복 도입으로 단일 패킷 손실 시 복구 속도 향상 | 한 번의 혼잡 이벤트에서 다중 패킷 손실 시 성능 저하 | |
부분적인 ACK 처리 방식 개선으로 다중 패킷 손실 복구 능력 향상 | 선택적 확인 응답을 지원하지 않는 네트워크 환경에서도 효과적 |
TCP NewReno는 SACK 옵션을 지원하지 않는 네트워크 환경에서도 효과적으로 동작하며, 오랫동안 표준적인 TCP 혼잡 제어 알고리즘으로 널리 사용되었다.
8.2. TCP BBR
8.2. TCP BBR
TCP BBR은 구글이 개발한 혼잡 제어 알고리즘으로, 기존의 패킷 손실 기반 방식과 근본적으로 다른 접근법을 채택한다. BBR은 "Bottleneck Bandwidth and Round-trip propagation time"의 약자로, 네트워크 경로의 대역폭과 왕복 지연 시간을 모델링하여 최적의 전송 속도를 결정한다. 이 알고리즘은 패킷 손실을 혼잡의 지표로 삼는 대신, 실제 네트워크 경로의 물리적 용량을 지속적으로 측정하고 이를 활용한다.
BBR의 핵심은 두 가지 메트릭, 즉 경로의 최대 대역폭(BtlBw)과 최소 왕복 지연 시간(RTprop)을 추정하는 데 있다. 알고리즘은 주기적으로 전송 속도를 일시적으로 높여 최대 대역폭을 탐색하고, 그 후 큐에 쌓이는 지연을 최소화할 수 있는 속도로 전송한다. 이는 네트워크 버퍼블로트 현상을 유발하지 않으면서도 높은 처리량과 낮은 지연을 동시에 달성하는 것을 목표로 한다. BBR의 동작 단계는 크게 스타트업, 대역폭 탐지, 지연 탐지, 정상 상태로 구분된다.
기존의 TCP Reno나 CUBIC TCP와 같은 손실 기반 혼잡 제어 알고리즘은 패킷 손실이 발생할 때까지 전송 속도를 증가시킨 후, 손실을 혼잡 신호로 간주해 속도를 급격히 낮춘다. 이 방식은 버퍼가 가득 차야 혼잡을 감지하므로 불필요한 큐잉 지연과 패킷 손실을 초래할 수 있다. 반면, BBR은 손실이 발생하기 전에, 즉 버퍼가 채워지기 시작하는 시점에서 이미 전송 속도를 조절한다. 결과적으로 BBR은 특히 고대역폭·고지연 네트워크 환경에서 더 안정적인 처리량과 예측 가능한 낮은 지연을 제공한다.
BBR은 구글의 내부 네트워크와 유튜브 등의 서비스에 적용되어 성능 향상을 입증했으며, 리눅스 커널에 공식적으로 포함되었다. 이후 BBRv2와 같은 개선판도 연구되고 있다. 그러나 모든 네트워크 조건에서 최적의 성능을 보장하지는 않으며, 특히 공정성 측면에서 기존의 TCP 흐름과의 공존 시 문제가 제기되기도 한다[8].
8.3. MPTCP (다중 경로 TCP)
8.3. MPTCP (다중 경로 TCP)
MPTCP는 단일 TCP 연결이 여러 네트워크 경로를 동시에 사용할 수 있도록 하는 TCP의 주요 확장 프로토콜이다. 기존 TCP는 하나의 IP 주소 쌍(출발지와 목적지) 사이에 단일 경로를 통해 연결을 설정하지만, MPTCP는 단일 논리적 연결 내에서 여러 서브플로우를 생성하여 데이터를 병렬로 전송한다. 이는 사용자 장치가 Wi-Fi와 셀룰러 네트워크를 동시에 보유하는 경우와 같이 여러 네트워크 인터페이스를 가진 현대 환경에서 특히 유용하다. MPTCP의 주요 목표는 대역폭 집계를 통한 처리량 향상, 경로 장애 시 연결 복원력 강화, 그리고 네트워크 간 부하 분산이다.
MPTCP의 동작 방식은 연결 설정 단계부터 다르다. 초기 핸드셰이크 과정에서 호스트는 MPTCP 지원을 협상하며, 이후 추가적인 서브플로우를 기존 연결에 설정한다. 각 서브플로우는 고유한 4-tuple(출발지 IP 주소, 출발지 포트 번호, 목적지 IP 주소, 목적지 포트 번호)을 가지지만, 모두 동일한 논리적 연결에 속한다. 데이터 시퀀스 번호는 연결 전체에서 관리되며, 송신 측은 이를 여러 서브플로우에 분산하여 전송한다. 수신 측은 서로 다른 경로를 통해 도착할 수 있는 패킷의 재정렬을 수행하여 애플리케이션에 순차적인 데이터 스트림을 전달한다.
MPTCP는 다음과 같은 장점과 함께 새로운 과제를 안고 있다.
장점 | 설명 |
|---|---|
대역폭 집계 | 여러 경로의 대역폭을 합쳐 전체 처리량을 높인다. |
복원력 향상 | 한 경로에 장애가 발생해도 다른 경로를 통해 연결을 유지한다. |
트래픽 분산 | 네트워크 혼잡을 개별 경로에 분산시킬 수 있다. |
핸드오버 지원 | 이동 중인 장치의 네트워크 전환을 매끄럽게 한다. |
반면, 패킷 재정렬로 인한 버퍼 관리 복잡성 증가, 여러 경로의 혼잡 제어를 조정해야 하는 문제, 그리고 중간 박스(예: NAT, 방화벽)의 호환성 문제 등이 구현상의 과제로 남아 있다. MPTCP는 IETF에서 표준화가 진행되었으며, iOS 및 리눅스 커널 등 일부 운영 체제와 서비스에 적용되어 실용화되고 있다.
9. TCP와 UDP 비교
9. TCP와 UDP 비교
전송 제어 프로토콜(TCP)과 사용자 데이터그램 프로토콜(UDP)은 인터넷 프로토콜 스위트의 핵심 전송 계층 프로토콜이지만, 설계 목적과 특성에서 근본적인 차이를 보인다. TCP는 신뢰성과 순서 보장에 중점을 둔 연결 지향형 프로토콜인 반면, UDP는 단순성과 속도를 우선시하는 비연결형 프로토콜이다. 이 차이는 각 프로토콜이 사용되는 애플리케이션 영역을 결정하는 주요 요인이다.
두 프로토콜의 핵심 특성을 비교하면 다음과 같다.
특성 | TCP (전송 제어 프로토콜) | UDP (사용자 데이터그램 프로토콜) |
|---|---|---|
연결 방식 | 연결 지향형 (가상 회선) | 비연결형 (데이터그램) |
신뢰성 | 높음 (확인 응답, 재전송, 순서 보장) | 낮음 (기본적인 오류 검출만 수행) |
전송 순서 보장 | 보장함 | 보장하지 않음 |
흐름 제어 / 혼잡 제어 | 있음 (슬라이딩 윈도우, 다양한 알고리즘) | 없음 |
헤더 오버헤드 | 큼 (20바이트 이상, 다양한 필드) | 작음 (8바이트 고정) |
전송 속도 | 상대적으로 느림 (설정 및 제어 오버헤드) | 상대적으로 빠름 |
통신 방식 | 1:1 (유니캐스트) | 1:1, 1:N, N:N (유니캐스트, 브로드캐스트, 멀티캐스트) |
주요 사용 예시 | 월드 와이드 웹(HTTP), 이메일(SMTP), 파일 전송(FTP), 원격 접속(SSH) | 도메인 네임 시스템(DNS), 실시간 스트리밍, VoIP, 온라인 게임, SNMP |
이러한 차이로 인해 TCP는 데이터의 완전하고 정확한 전달이 필수적인 애플리케이션에 적합하다. 웹 페이지 로딩이나 파일 다운로드 시 데이터의 일부가 손실되면 전체 내용을 이해할 수 없기 때문이다. 반면, UDP는 작은 지연 시간이 데이터의 일부 손실보다 중요한 실시간 애플리케이션에서 선호된다. 예를 들어, 화상 통화에서 몇 프레임의 픽셀 데이터가 유실되어도 통화는 지속될 수 있지만, TCP의 재전송 대기로 인한 지연은 대화의 자연스러운 흐름을 심각하게 방해한다.
결론적으로, TCP와 UDP의 선택은 애플리케이션의 요구사항에 따라 달라진다. '정확성'이 최우선이라면 TCP를, '신속성'과 '실시간성'이 더 중요하다면 UDP를 선택하는 것이 일반적이다. 일부 현대 프로토콜은 이 두 극단 사이에서 자신만의 신뢰성 메커니즘을 애플리케이션 계층에 구현하기도 한다[9]] 프로토콜은 UDP 위에 신뢰성과 보안을 구축함].
