컴퓨터 네트워킹 요약 - 3. 트랜스포트 계층

3.1. 트랜스포트 계층 서비스 및 개요(Introduction and Transport-Layer Services)

트랜스포트 계층 프로토콜은 서로 다른 호스트에서 동작하는 애플리케이션 프로세스들 간의 논리적 통신(logical communication)을 제공한다. 논리적 통신은 애플리케이션의 관점에서 보면, 물리적인 하위 구조를 신경쓰지 않고 프로세스들을 실행하는 호스트들이 직접 연결된 것처럼 보인다는 것을 의미한다.

3.1.1. 트랜스포트 계층과 네트워크 계층사이의 관계(Relationship Between Transport and Network Layers)

트랜스포트 계층은 프로토콜 스택에서 네트워크 계층 바로 상위에 존재한다.

종단 시스템 안에서, 트랜스포트 프로토콜은 프로세스에서 네트워크 경계(네트워크 계층)까지 메세지를 운반하며, 또한 반대 방향으로 메세지를 운반한다. 반면, 네트워크 프로토콜은 라우터를 거쳐 다른 종단 시스템까지 가는 것을 관리한다.

컴퓨터 네트워크는 애플리케이션에게 서로 다른 서비스를 제공하도록 하는 다양한 트랜스포트 프로토콜을 만들 수 있게 한다.

트랜스포트 계층이 제공할 수 있는 서비스는 하위 계층인 네트워크 계층의 서비스에 의해서 제약받는다. 네트워크 계층이 트랜스포트 계층 세그먼트에 대한 지연/대역폭 보장을 제공할 수 없다면, 트랜스포트 계층은 프로세스끼리 전송하는 메세지에 대한 지연/대역폭 보장을 제공할 수 없다.

하지만 네트워크 계층이 상응하는 서비스를 제공하지 못할 때에도, 특정 서비스는 트랜스포트 계층이 제공할 수도 있다. 예를 들어, 신뢰적 데이터 전송, 데이터 암호화가 있다.

3.1.2. 인터넷 트랜스포트 계층의 개요(Overview of the Transport Layer in the Internet)

인터넷, 일반적으로 TCP/IP 네트워크에는 비신뢰적이고 비연결형인 UDP과 신뢰적이고 연결지향형인 TCP 프로토콜이 있다. 트랜스포트 계층 패킷을 세그먼트라고 한다.

UDP, TCP에 앞서 인터넷의 네트워크 계층의 용어는 다음과 같다. 네트워크 계층 프로토콜은 인터넷 프로토콜, 줄여서 IP라고 부른다.

IP 서비스 모델은 호스트들 간에 논리적 통신을 제공하는 최선형 전달 서비스(best-effort delivery service)이다. IP는 세그먼트 전달을 위해 최대한 노력하지만, 전달을 보장하지 않고 세그먼트가 순서대로 전달되는 것도 보장하지 않는다. 이 때문에, IP를 비신뢰적인 서비스(unreliable service)라 한다.

UDP와 TCP의 기본적인 기능은 호스트 간의 IP 전달 서비스를 호스트에서 동작하는 두 프로세스 간의 전달 서비스로 확장하는 것이다. “호스트-대-호스트 전달”을 “프로세스-대-프로세스”로 확장하는 것을 트랜스포트 다중화(transport multiplexing)와 역다중화(demultiplexing)라고 부른다.

UDP는 IP와 같이 비신뢰적인 서비스이다. 전송되는 데이터가 손상되지 않는 것을 보장하지 않는다.

TCP는 신뢰적인 데이터 전달(reliable data transfer)을 제공한다. 한 TCP 연결이 과도한 양의 트래픽으로 호스트들 사이의 스위치와 링크에 넘치지(swamping) 않도록 혼잡제어도 제공한다. 흐름제어, 순서번호, 확인응답, 타이머 등을 사용한다.

3.2. 다중화와 역다중화(Multiplexing and Demultiplexing)

목적지 호스트에서 트랜스포트 계층은 바로 아래의 네트워크 계층으로부터 세그먼트를 수신한다. 트랜스포트 계층은 호스트에서 동작하는 여러 프로세스 중 올바른 프로세스에게 이 세그먼트의 데이터를 전달한다.

트랜스포트 계층은 데이터를 직접 프로세스로 전달하지 않는다. 대신에 중간 매개자인 소켓에게 전달한다.

트랜스포트 계층 세그먼트의 데이터를 올바른 소켓으로 전달하는 작업을 역다중화라고 한다.

출발지 호스트에서 소켓으로부터 데이터를 모으고, 세그먼트를 생성하기 위해 데이터에 헤더 정보(역다중화에 필요)로 캡슐화하고, 세그먼트를 네트워크 계층으로 전달하는 작업을 다중화라고 한다.

다중화에는 두 가지 요구사항이 필요하다.

  1. 소켓은 유일한 식별자를 가진다.
  2. 각 세그먼트를 세그먼트가 전달될 소켓을 가르키는 특별한 필드를 가진다. 즉, 출발지 포트 번호 필드(source port number field)와 목적지 포트 번호 필드(destination port number field)이다.

호스트의 각 소켓은 포트 번호를 할당받는다. 세그먼트가 호스트에 도착하면, 트랜스포트 계층은 목적지 포트 번호를 검사하고 상응하는 소켓으로 세그먼트를 보낸다. 그러면 세그먼트의 데이터는 소켓을 통해 프로세스로 전달된다.

3.2.1. 비연결형 다중화와 역다중화(Connectionless Multiplexing and Demultiplexing)

clientSocket = socket(AF_INET, SOCK_DGRAM) // UDP 소켓 생성, 트랜스포트 계층이 포트 번호 자동으로 사용되지 않는 번호 할당
clientSocket.bind(('', 19157))		   // 포트 번호 명시

트랜스포트 계층이 세그먼트를 네트워크 계층에 전달하면, 네트워크 계층은 세그먼트를 IP 데이터그램으로 캡슐화하고 최선형 전달 서비스로 수신 호스트로 전달한다.

수신 호스트에서 세그먼트 목적지 포트를 검사하여 적절한 소켓으로 세그먼트를 보낸다. 즉, (목적지 IP, 목적지 포트)가 식별에 사용된다. 출발지 포트는 수신 호스트가 송신 호스트에게 보내기 원할 때 사용된다.

3.2.2. 연결지향형 다중화와 역다중화(Connection-Oriented Multiplexing and Demultiplexing)

2.7.2절에서 살펴보았듯이 TCP 서버는 환영 소켓과 각 클라이언트에 대응되는 소켓을 가지고 있다. 따라서, UDP 소켓과 달리 TCP 소켓은 (출발지 IP, 출발지 포트 번호, 목적지 IP, 목적지 포트)가 식별에 필요하다.

3.2.3. 웹 서버와 TCP(Web Servers and TCP)

TCP을 사용하는 HTTP 웹 서버는 각각의 연결에 따라서 새로운 프로세스를 만든다. 이들 프로세스는 각자 연결 소켓을 가지며, 이 연결 소켓을 통해서 HTTP 요청을 수신하고 응답한다.

그러나 오늘날의 많은 웹 서버들은 하나의 프로세스만 사용한다. 각각의 새로운 클라이언트 연결을 위해 새로운 연결 소켓과 함께 새로운 스레드를 생성한다.

3.3. 비연결형 트랜스포트: UDP(Connectionless Transport: UDP)

UDP는 신뢰적인 데이터 전송 서비스를 제공하지 않지만, 아래와 같은 장점을 지닌다.

UDP에서는 프로세스가 무슨 데이터를 언제 보낼지 더 정교하게 제어할 수 있다. 프로세스가 데이터를 UDP에 전달하자마자, 세그먼트가 만들어지고 즉시 네트워크 계층으로 전달된다. 애플리케이션이 UDP의 기본 세그먼트 전달 외에 필요한 기능을 구현할 수 있다.

UDP는 연결 설정이 없다. TCP처럼 세 방향 핸드셰이크를 하지 않으며, 예비동작 없이 데이터를 전송한다.

UDP는 연결 상태가 없다. TCP는 종단 시스템에서 연결 상태(버퍼, 혼잡제어 파라미터 등)을 유지한다. UDP는 어떤 것도 기록하지 않는다.

TCP가 세그먼트마다 20바이트의 헤더 오버헤드를 갖는 반면에 UDP는 단지 8바이트의 오버헤드를 가진다.

이런 장점이 있기에, 적은 양의 패킷 손실이 허용되는 애플리케이션들은 UDP를 사용할 수도 있다.

3.3.1. UDP 세그먼트 구조(UDP Segment Structure)

UDP 세그먼트에는 출발지 포트 번호, 목적지 포트 번호, 길이, 체크섬(checksum), 애플리케이션 데이터가 있다.

  • 포트번호는 역다중화를 위해 쓰인다.
  • 길이는 헤더를 포함하는 UDP 세그먼트의 길이를 나타낸다.
  • 체크섬은 세그먼트에 오류가 발생했는지를 검사하기 위해 수신 호스트에 의해 사용된다.
  • 애플리케이션 데이터는 DNS 질의 응답, 비디오 샘플 등이 있다.

3.3.2. UDP 체크섬(UDP Checksum)

UDP 체크섬은 오류 검출을 제공한다. 즉, 체크섬은 세그먼트가 출발지로부터 목적지로 이동 했을 때, 세그먼트 안의 비트에 대한 변경사항(예: 링크의 잡음에 의해서 또는 라우터에서 저장되는 동안)이 있는지 검사한다.

UDP는 세그먼트 안에 있는 16비트 워드를 전부 더한 후에 1의 보수를 수행한다. 이때 최상위 비트에서 발생하는 오버플로우는 버린다.

// 3개의 워드가 있다고 가정

// 아래 세개 워드를 더함
0110011001100000
0101010101010101
1000111100001100

// 먼저 위의 두개를 더함
0110011001100000
0101010101010101
----------------
1011101110110101

// 위의 결과와 세번째 비트를 더함, 맨 왼쪽 오버플로우는 버려짐
1011101110110101
1000111100001100
----------------
0100101011000010

// 1의 보수를 취함
1011010100111101

수신자에서는 체크섬을 포함한 4개의 모든 16비트 워드들을 더한다. 만약 패킷에 오류가 없다면, 수신자에서의 합은 1111111111111111이 된다. 하나라도 0이 있다면 오류가 발생한 것이다.

어떤 링크 계층 프로토콜은 오류 검사를 수행하지 않고, 세그먼트가 라우터의 메모리에 저장될 때 비트 오류가 생길 수 있으므로, 트랜스포트 계층에서 오류 검사를 해야한다.

그러나 UDP는 오류가 생겨도 이를 회복하지 않는다. 손상된 세그먼트를 그냥 버리거나, 경고와 함께 손상된 세그먼트를 애플리케이션에게 넘겨준다.

3.4. 신뢰성 있는 데이터 전송의 원리(Principles of Reliable Data Transfer)

신뢰적인 데이터 전송 문제는 트랜스포트 계층뿐만 아니라 링크 계층과 애플리케이션 계층에서도 발생 할 수 있다.

상위 계층에게 제공되는 서비스 추상화는 데이터가 전송될 수 있는 신뢰적인 채널의 서비스 추상화다. 신뢰적인 채널에서는 전송된 데이터가 손상되거나 손실되지 않는다. 그리고 모든 데이터는 전송된 순서대로 전달된다.

이러한 서비스 추상화를 구현하는 것은 신뢰적인 데이터 전송 프로토콜(reliable data transfer protocol)의 의무이다.

3.4.1. 신뢰적인 데이터 전달 프로토콜의 구축(Building a Reliable Data Transfer Protocol)

3.4.1.1. 완벽하게 신뢰적인 채널 상에서의 신뢰적인 데이터 전송: rdt1.0 (Reliable Data Transfer over a Perfectly Reliable Channel: rdt1.0)

먼저, 하위 채널이 완전히 신뢰적인 가장 간단한 경우를 고려한다.

송신 측은 상위 계층의 이벤트 발생 시 데이터를 받고, 이를 포함한 패킷을 생성한다. 그리고 패킷을 하위 채널로 송신한다.

수신 측은 하위 채널의 이벤트 발생 시 하위 채널으로부터 패킷을 수신하고, 데이터를 추출한다. 그리고 데이터를 상위 계층으로 전달한다.

완전히 신뢰적인 채널에서는 오류가 생길 수 없으므로, 수신 측이 송신 측에게 어떤 피드백(feedbakc)도 제공할 필요가 없다. 또한 수신자는 송신자가 데이터를 송신하자마자 수신할 수 있다고 가정했으므로, 수신자가 송신자에게 “천천히”라는 것을 요청할 필요도 없다.

3.4.1.2. 비트 오류가 있는 채널 상에서의 신뢰적 데이터 전송: rdt2.0 (Reliable Data Transfer over a Channel with Bit Errors: rdt2.0)

패킷 안의 비트들은 하위 채널에서 손상될 수 있다. 비트 오류는 패킷이 전송/전파되거나 버퍼링될 때 네트워크의 물리적 구성요소에서 일반적으로 발생한다. rdt2.0 에서는 패킷들이 송신된 순서대로 수신된다고 가정한다.

패킷이 정확하게 혹은 잘못 수신되어 반복이 필요한지를 수신자가 송신자에게 알려줄 수 있도록 제어 메세지(control messages)가 사용될 수 있다. 컴퓨터 네트워크에서 재전송을 기반으로 하는 신뢰적 데이터 전송 프로토콜은 자동 재전송 요구(Automatic Repeat reQuest, ARQ) 프로토콜로 알려져 있다.

비트 오류를 처리하기 위해 다음과 같은 기능들이 ARQ 프토로콜에 필요하다.

  • 오류 검출: 체크섬과 같은 추가적인 비트들이 필요하다.
  • 수신자 피드백: 수신자의 상태를 알기 위해 긍정 확인응답(ACK)과 부정 확인응답(NAK) 등이 필요하다.
  • 재전송: 오류를 가지고 수신된 패킷은 송신자가 재전송한다.

송신 측은 패킷을 보낸 후 ACK 또는 NAK 패킷을 기다린다. 기다리는 동안은 상위 계층의 데이터는 더 받을 수 없다. 이 행동 때문에 rdt2.0은 전송-후-대기(stop-and-wait) 프로토콜로 알려져 있다.

ACK 응답이 오면 정확하게 수신되었다는 뜻이므로, 상위 계층의 데이터를 기다린다. NAK 응답이 오면 마지막 패킷을 재전송하고, 다시 응답을 기다린다.

수신 측은 수신된 패킷이 손상되었는지 확인하고 ACK 또는 NAK 응답을 보낸다.

rdt2.0은 ACK/NAK 응답 패킷 손상 가능성을 고려하지 않는다. 이런 경우 송신자는 수신자가 전송된 데이터의 마지막 부분을 올바르게 수신했는지를 알 수 없다.

이를 해결하기 위해 송신자가 손상된 ACK/NAK 패킷을 받으면 현재 데이터 패킷을 다시 송신한다. 이는 중복 패킷(duplicate packet)을 전송할 수 있으므로, 수신자에게 도착하는 패킷이 새로운 데이터를 포함하는 지를 알려줄 방법이 필요하다.

패킷이 재전송된 것인지를 판별하기 위해, 패킷에 순서번호(sequence number)를 삽입한다. 0, 1을 반복된 순서로 패킷에 추가하여 전송한다.

개선된 rdt2.1에서는 손상된 패킷이 수신되면, NAK을 전송한다. 손상되지 않았고, 패킷 순서가 일치할 때는 데이터를 상위 계층으로 올리고 ACK을 전송한다.
손상되지 않았고, 패키 순서가 다르면 ACK만 전송한다.

수신자가 NAK을 사용하지 않고 ACK 응답만 사용하는 rdt2.2도 있다. ACK에 0, 1 인수를 포함하여 응답한다. 수신자는 패킷 순서가 다르거나 손상된 패킷이라면 ACK 에 이전 패킷 번호를 넣어 응답한다. (예: 0번을 기다리는데, 1번이 오거나 손상된 패킷)

3.4.1.3. 비트 오류와 손실 있는 채널 상에서의 신뢰적 데이터 전송: rdt3.0(Reliable Data Transfer over a Lossy Channel with Bit Errors: rdt3.0)

오늘날의 컴퓨터 네트워크에서는 비트 손상외에도 하위 채널이 패킷을 손실하는 경우도 있다. rdt3.0 은 rdt2.2에 추가적으로 카운트 다운 타이머(countdown timer)를 사용한다.

송신 측은 패킷이 손실되어 ACK 응답이 일정 시간 동안 오지 않으면 재전송을 한다. 일정 시간을 현명하게 선택해야 중복 패킷을 줄일 수 있다.

3.4.2. 파이프라인된 신뢰적 데이터 전송 프로토콜(Pipelined Reliable Data Transfer Protocols)

rdt3.0은 오늘날의 고속 네트워크에서 성능을 만족시킬 수 없다. rdt3.0이 전송-후-대기 프로토콜이기 때문이다. 비트를 전송하는 시간이 대기시간 보다 짧으며, 1Gbps 링크를 가져도 200 kbps 처럼 적은 유효 처리량(effective throughput)을 가지게 된다.

파이프라이닝(pipelining)은 확인응답을 기다리지 않고 여러 패킷을 전송하도록 허용한다. 전송 중인 패킷은 파이프라인에 채워 넣는다.

이 방식에서는 순서 번호의 범위가 커져야 한다. 확인응답이 안된 여러 패킷이 있을지도 모르기 때문이다.

그리고 송신/수신 측은 패킷을 버퍼링해야 한다. 송신자는 전송되었으나 확인응답 되지 않는 패킷을 버퍼링해야 한다. 수신자도 수신한 패킷을 버퍼링해야 한다.

3.4.3. N부터 반복(Go-Back-N, GBN)

GBN 프로토콜에서 송신자는 확인응답을 기다리지 않고 여러 패킷을 전송할 수 있다. 그러나 파이프라인에서 확인응답이 안된 패킷의 최대 허용 수 N보다 크지 않아야 한다. N을 윈도우 크기(window size)라고도 부르며, GBN 프로토콜을 슬라이딩 윈도우 프로토콜(sliding-window protocol)이라고도 부른다.

송신자는 세 가지 타입의 이벤트에 반응한다. (1) 상위로부터의 호출: 송신자는 상위 계층이 데이터를 보내려고 할 때, N개의 확인응답 되지 않은 패킷이 있는지를 확인한다. 윈도우가 가득 차 있지 않다면 패킷을 생성하고 송신한다. 아니라면 상위 계층으로 반환한다.

(2) ACK의 수신: 순서번호 n을 가진 패킷에 대한 확인응답은 누적 확인응답(cumulative acknowledgment)으로 인식된다. n까지의 모든 패킷들이 올바르게 수신되었다고 판단한다.

(3) 타임아웃 이벤트: 전송-후-대기 프로토콜 같이, 타임아웃이 발생한다면, 전송되었지만 아직 확인응답 되지 않은 모든 패킷을 다시 송신한다.

수신자의 행동은 단순하다. 순서번호 n을 가진 패킷이 오류 없이, 순서대로 수신된다면 n에 대한 ACK를 송신한다. 그 외의 경우에는 패킷을 버리고, 가장 최근에 제대로 수신된 패킷의 순서에 대한 ACK를 재전송한다.

3.4.4. 선택적 반복(Selective Repeat, SR)

GBN은 패킷 하나의 오류 때문에 많은 패킷을 재전송한다. SR 프로토콜은 수신자에서 오류가 있다고 한 패킷만 재전송한다.

송신자는 다음과 같이 행동한다. (1) 상위 계층에서 데이터 받음: 순서번호가 윈도우 내에 있으면 패킷으로 만들어 송신한다. 아니라면 버퍼에 저장하거나 상위 계층으로 돌려준다.

(2) 타임아웃: 각 패킷은 자신의 타이머를 가진다. 타임아웃된 패킷만 재전송된다.

(3) ACK 수신: ACK와 같이 온 순서번호의 패킷을 수신된 것으로 표기한다. 만약 순서번호가 윈도우의 send_base(시작 지점)이라면, send_base를 가장 작은 순서번호를 가지고 아직 확인응답 되지 않는 패킷의 위치로 옮긴다. 이동후 윈도우 안에 순서번호를 가진 미전송 패킷이 있다면, 이를 전송한다.

수신자는 다음과 같이 행동한다. (1) 윈도우 범위 안의 순서번호[rcv_base, rcv_base+N-1]를 가진 패킷이 오류없이 수신 될 때: ACK를 보내는 것은 같고, 순서번호에 따라 달라진다.

패킷의 순서번호가 rcv_base와 같지 않다면, 버퍼에 저장한다. rcv_base와 같다면, 이 패킷과 버퍼에 저장된 연속된 패킷들을 상위 계층으로 전달한다. 예를 들어, rcv_base=2가 온다면 버퍼의 3, 4, 5 패킷이 같이 전달될 수 있다.

(2) [rcv_base-N, rcv_base-1] 내의 순서번호를 가진 패킷이 온다면: 이전에 확인응답한 것이라도, ACK를 보낸다.

(3) 이 외의 경우, 패킷을 무시한다.

앞의 내용들은 패킷의 순서가 바뀔 수 없다는 가정이었다. 실제로는 순서가 바뀌어, 송신자와 수신자의 윈도우가 x를 포함하지 않고 있더라도, 순서번호 또는 확인응답번호 x를 가진 패킷의 복사본들이 생길 수 있다.

이를 막기 위해 송신자가 순서번호 x를 가진 이전에 송신된 패킷들이 더 이상 네트워크에 없다는 것을 어느 정도 확신할 때까지 순서번호가 재사용되지 않게 한다.

3.5. 연결지향형 트랜스포트: TCP(Connection-Oriented Transport: TCP)

3.5.1. TCP 연결(The TCP Connection)

TCP는 프로세스가 데이터를 보내기 전에, 두 프로세스가 서로 핸드셰이크를 먼저 해야하므로 연결지향형(connection-oriented)이다. TCP 프로토콜은 종단 시스템에서만 동작하고, 중간의 네트워크 요소(라우터 등)은 TCP 연결을 보지 못하고 데이터그램만 본다.

TCP 연결은 양방향 통신이 가능한 전이중(full-duplex) 서비스를 제공한다. 또한 TCP 연결은 항상 단일 송신자와 단일 수신자 사이의 점대점(point-to-point)이다.

TCP 연결 설정은 다음과 같이 이루어진다. 먼저 클라이언트가 특별한 TCP 세그먼트를 보낸다. 서버가 응답하고, 마지막으로 클라이언트가 응답한다. 두 호스트 사이에 3개의 세그먼트가 보내지므로, 세 방향 핸드셰이크라 부른다.

프로세스의 데이터는 소켓을 거쳐 TCP 송신 버퍼(send buffer)에 저장된다. TCP는 송신 버퍼에서 TCP 세그먼트(TCP 헤더와 데이터를 합침)를 만들어서 네트워크 계층으로 보낸다.

TCP가 상대에게서 세그먼트를 수신하면, 세그먼트의 데이터는 수신 버퍼(receive buffer)에 저장된다. 그리고 소켓을 거쳐 프로세스에게 전달된다.

3.5.2. TCP 세그먼트 구조(TCP Segment Structure)

TCP 세그먼트는 헤더 필드와 데이터 필드로 구성되어 있는데, MSS(maximum segment size)가 데이터 필드의 크기를 제한한다. TCP 헤더는 일반적으로 20바이트이다.

TCP 헤더는 다음과 같은 필드를 포함한다.

  • 출발지, 목적지 포트 번호
  • 순서번호, 확인응답번호
  • 수신 윈도우(3.5.5. 흐름제어에 사용)
  • 헤더길이 - 옵션(option) 필드 때문에 가변적인 길이가 될 수 있다.
  • 옵션 - 송신자와 수신자가 MSS를 조절하거나 윈도우 확장 요소, 타임 스탬프에 이용된다.
  • 플래그(flag) - ACK(확인응답), CWR/ECE(3.7.2. 혼잡표시), RST/SYN/FIN(연결 설정/해제), PSH(즉시전달), URG(긴급)
  • 긴급 데이터 포인터 - URG비트 사용 시 긴급 데이터의 마지막 바이트 위치를 가르킴
  • 체크섬

3.5.2.1. 순서번호와 확인응답 번호(Sequence Numbers and Acknowledgment Numbers)

TCP는 데이터를 구조화하지 않고, 단지 순서대로 정렬된 바이트 스트림으로 본다. 따라서 세그먼트에 대한 순서번호는 세그먼트에 있는 첫 번째 바이트의 바이트 스트림 번호이다.

예를 들어, 데이터 스트림이 500,000바이트, MSS가 1,000바이트라면, 첫 번째 세그먼트는 0, 두 번째 세그먼트는 1,000, … 의 순서 번호를 갖는다.

확인응답 번호는 약간 까다롭다. 먼저, TCP 연결은 전이중 방식임을 상기하자. 호스트 A가 자신의 세그먼트에 삽입하는 확인응답 번호는, 호스트 A가 호스트 B로부터 기대하는 다음 바이트의 순서번호이다.

예를 들어, 호스트 A가 호스트 B로부터 0~535의 바이트를 포함하는 세그먼트와 900~1000의 바이트를 포함하는 세그먼트를 받았다면, A의 다음 확인응답 번호는 536이다. 그리고 순서가 틀린 900~1000 세그먼트는 버퍼에서 기다리게 된다.

3.5.2.2. 텔넷: 순서번호와 확인번호 사례연구(Telnet: A Case Study for Sequence and Acknowledgment Numbers)

텔넷은 대화형 애플리케이션이고, 암호화되지 않아 SSH 프로토콜에 비해 잘 쓰이지 않는다.

텔넷에서 사용자가 입력한 문자는 원격 호스트에 송신되고, 복사본이 사용자에게 반송된다.

3.5.3. 왕복시간 예측과 타임아웃(Round-Trip Time Estimation and Timeout)

3.5.3.1. 왕복시간 예측(Estimating the Round-Trip Time)

세그먼트에 대한 SampleRTT 는 세그먼트가 송신된 시간으로부터 긍정응답이 도착한 시간까지의 시간이다. TCP는 전송된 모든 세그먼트가 아닌 한 번에 하나의 SampleRTT 측정만을 시행한다. 이때, 재전송한 세그먼트에 대한 SampleRTT는 포함하지 않는다.

SampleRTT는 라우터의 혼잡성과 종단 시스템의 부화 변화 때문에 불규칙적이다. 따라서 평균값을 사용한다. 아래 식에서 a=0.125 값이 RFC6298에서 권장되고 있다.

EstimatedRTT = (1 - a) * EstimateRTT + a * SampleRTT

EstimatedRTT는 SampleRTT의 가중평균(weighted average)이며, 통계에서 이런 평균은 지수적 가중 이동 평균(exponential weighted moving average)이라 한다.

RTT의 예측 외에도 RTT 변화율을 측정하는 것도 유용하다. RTT 변화율을 의미하는 DevRTT는 SampleRTT가 EstimatedRTT로부터 얼마나 벗어나는지에 대한 예측이다. b=0.25 가 권장 값이다.

DevRTT = (1 - b) * DevRTT + B * SampleRTT - EstimatedRTT

3.5.3.2. 재전송 타임아웃 주기의 설정 및 관리(Setting and Managing the Retransmission Timeout Interval)

재전송 타임아웃 주기를 TCP에서는 다음과 같이 사용한다.

TimeoutInterval = EstimatedRTT + 4 * DevRTT

또한 타임아웃이 발생할 때, TimeoutInterval 값을 두배로 하여, 곧 확인응답할 후속 세그먼트에게 발생할 수 있는 타임아웃을 피하도록 한다.

3.5.4. 신뢰적인 데이터 전달(Reliable Data Transfer)

TCP는 네트워크 계층(IP 서비스)의 비신뢰적인 최선형 서비스에서 신뢰적인 데이터 전달 서비스를 제공한다.

앞에서는 신뢰적인 데이터 전송을 위해 각 세그먼트당 타이머가 있다고 하였다. 하지만 이는 오버헤드이기에 TCP 프로토콜은 단일 전송 타이머를 사용한다.

먼저, 단순화된 구조에서 송신자의 행동은 다음과 같다. (1) 애플리케이션으로부터 데이터를 받고 세그먼트를 만든다. 그리고 IP에게 세그먼트를 넘기면서, 타이머가 실행 중이 아니라면 시작한다.

(2) 타임아웃이 일어난다면, 확인응답을 받지 못한 세그먼트 중 순서번호가 가장 작은 것을 재전송한다.

(3) 순서번호 y에 대응되는 ACK를 받고, y가 SendBase(확인응답이 되지 않은 가장 오래된 순서번호) 보다 크다면 SendBase=y로 갱신하고, 아직 확인응답 안된 세그먼트들이 존재한다면 타이머를 다시 시작한다.

3.5.4.1. 몇 가지 흥미로운 시나리오(A Few Interesting Scenarios)

호스트 A가 B로 데이터를 보내는 3가지 시나리오를 살펴본다.

(1-1) A가 Seq=92, 8bytes data를 보낸다. (1-2) ACK=100이 손실된다. (1-3) 타임아웃으로 Seq=92, 8bytes data 재전송된다.

(2-1) A가 Seq=92, 8bytes data / Seq=100, 20bytes data을 동시에 보낸다. (2-2) B가 ACK=100, ACK=120을 보내지만 A에 전달되기 전에, Seq=92의 타임아웃이 먼저 일어나 Seq=92만 재전송이 일어난다. (2-3) B는 120까지 받았으므로 재전송에 ACK=120을 보낸다.

(3-1) A가 Seq=92, 8bytes data / Seq=100, 20bytes data을 동시에 보낸다. (3-2) B가 ACK=100, ACK=120을 보내지만 ACK=100이 손실된다. (3-3) A는 ACK=120을 받았으므로, ~119까지 B가 수신했다는 것을 알고 아무것도 재전송하지 않는다.

3.5.4.2. 타임아웃 주기 두배로 설정(Doubling the Timeout Interval)

TCP는 재전송 때마다 마지막 EstimateRTT와 DevRTT로부터 타임아웃값을 가져오는 것이 아니라 타임아웃 주기를 이전 값의 두배로 설정한다.

이 방식은 제한된 형태의 혼잡제어를 제공한다. 타이머 만료는 주로 네트워크 혼잡에 의해 발생한다.

즉, 경로에서 하나 이상의 라우터 큐에 있는 많은 패킷이 패킷의 손실이나 큐 대기의 원인이 된다. 혼잡할 때 전송을 계속하면 그 혼잡은 더욱 악화될 것이다. 따라서 더 긴 간격으로 재전송한다.

3.5.4.3. 빠른 재전송(Fast Retransmit)

긴 타임아웃 주기는 잃어버린 패킷을 다시 보내기 전에 송신자를 오랫동안 기다리게 한다.

송신자는 3개의 중복 ACK를 수신하는 경우, 손실 세그먼트를 재전송하는 빠른 재전송을 한다. 중복 ACK는 수신자가 기다리는 것보다 더 큰 순서번호를 받았을 때 발생한다.

8 bytes data를 지닌 Seq=92, Seq=100, Seq=108, Seq=116, Seq=124을 송신할 때, Seq=100이 손실되었다면, 92, 108, 116, 124에 대한 ACK는 전부 100이 될 것이다.

3.5.4.4. GBN인가 SR인가?(Go-Back-N or Selective Repeat?)

TCP 송신자는 확인응답 안된 가장 작은 순서번호(SendBase)와 전송될 다음 순서번호를 유지한다. GBN과 유사하지만, TCP은 순서가 바뀐 세그먼트들을 버퍼링도 한다.

선택적 확인응답(selective acknowledgment)이라고 하는 TCP에 제안된 수정은, TCP 수신자가 마지막으로 올바로 수신된, 순서가 맞는 세그먼트에 대해 누적 확인응답을 하기 보다는 순서가 틀린 세그먼트에 대해서 선택적으로 확인응답을 하게 한다.

선택적 재전송과 결합되었을 경우 TCP는 SR 프로토콜과 유사하다. 그래서 TCP는 GBN과 SR의 혼합으로 분류하는 것이 적당하다.

3.5.5. 흐름제어(Flow Control)

TCP는 송신자가 수신자의 버퍼를 오버플로 시키는 것을 방지하기 위해서 애플리케이션에게 흐름제어 서비스(flow-control service)를 제공한다. 수신하는 애플리케이션이 읽는 속도와 송신자가 전송하는 속도를 같게 한다.

이 절에서는 TCP 수신자가 순서가 틀린 세그먼트를 버린다고 가정한다. TCP 송신자는 수신 윈도우(receive window)라는 변수를 유지하여 흐름제어를 제공한다. 수신 윈도우는 수신 측에서 가용한 버퍼 공간이 얼마나 남아있는지를 송신자에게 알려주는 데 사용된다.

수신 버퍼의 크기를 RcvBuffer, 수신 측 프로세스가 버퍼에서 읽은 데이터 스트림의 마지막 바이트의 수를 LastByteRead, 수신 측의 수신 버퍼에 저장된 데이터 스트림의 마지막 바이트의 수를 LastByteRcvd 라 하자. 그러면 수신 윈도우, rwnd=RcvBuffer - (LastByteRcvd - LastByteRead)가 된다.

수신 측은 세그먼트의 윈도우 필드에 rwnd값을 설정함으로써 송신 측에 자신의 여유 공간을 알려준다. 송신 측은 LastByteSent, LastByteAcked 변수를 유지하는데, LastByteSent - LastByteAcked 는 확인응답이 안된 데이터 양이다. 이 값을 rwnd 보다 작게 유지하여 수신 버퍼에 오버플로가 발생하지 않도록 한다.

수신 측이 rwnd=0 을 알리고 더이상 아무것도 전송하지 않는다면, 송신 측은 보낼 데이터가 있더라도 멈추게 된다. TCP 명세서는 이런 문제를 해결하기 위해, 수신 측의 수신 윈도우가 0이라면, 수신 측이 1바이트 데이터로 세그먼트를 계속 전송하도록 요구한다.

3.5.6. TCP 연결 관리(TCP Connection Management)

TCP 연결 설정 시작은 다음과 같다. 두 호스트 사이에서 3개의 패킷이 송신되므로 TCP 연결 설정 절차를 세 방향 핸드셰이크라고 부른다.

1단계: 클라이언트 측 TCP가 서버 TCP에게 특별한 TCP 세그먼트를 송신한다. 이 세그먼트에는 데이터가 포함되지 않으나, 헤더의 SYN 비트값이 1이다. 때문에 SYN 세그먼트라고도 부른다. 추가로, 세그먼트에 임의로 선택한 최초의 순서번호를 넣는다.

2단계: 서버가 SYN 세그먼트를 받으면, TCP 버퍼와 변수들을 할당한다. 그리고 연결 승인 세그먼트를 보낸다. 이 세그먼트에는 데이터가 없고, SYN 비트, 확인응답 번호, 서버가 선택한 최초의 순서번호가 포함된다. 때때로, SYNACK 세그먼트라고도 불린다.

3단계: 클라이언트가 SYNACK 세그먼트를 받으면, 버퍼와 변수들을 할당한다. 그리고 SYN 비트값 0, 확인응답 번호를 세그먼트에 넣어 서버로 보냄으로써, 서버의 SYNACK 세그먼트를 확인한다. 여기서 부터는 데이터가 포함될 수 있다.

서버나 클라이언트가 TCP 연결을 끝낼 수 있다. 예를 들어 클라이언트가 세그먼트 헤더에 FIN 비트를 1로 하여 보내고 ACK 응답을 받는다.

그 후, 서버가 동일하게 FIN 비트를 1로 하여 보내고 ACK 응답을 받으면, 연결이 종료된다. 클라이언트는 서버가 ACK 을 제대로 받도록 30초 등 일정 시간동안 TIME_WAIT 상태로 있다가 종료된다.
이 시점에서 두 호스트의 모든 자원들은 할당이 해제된다.

클라이언트가 SYN 세그먼트를 보냈지만, 서버의 목적지 포트에서 아무것도 실행이 되지 않을 때는 RST 비트가 1로 켜진 리셋 세그먼트를 답변받을 수도 있다. 이는 클라이언트가 세그먼트를 재전송하지 않게한다. 혹은 SYN 세그먼트가 방화벽에 차단되어, 아무것도 받지 못할수도 있다.

3.6. 혼잡제어의 원리(Principles of Congestion Control)

네트워크 혼잡 원인을 처리하기 위해서 네트워크 혼잡을 일으키는 송신자를 억제하는 메커니즘(mechanisms)이 필요하다.

3.6.1. 혼잡의 원인과 비용(The Causes and the Costs of Congestion)

3.6.1.1. 시나리오1: 2개의 송신자, 무한 버퍼를 갖는 하나의 라우터(Scenario 1: Two Senders, a Router with Infinite Buffers)

두 송신자가 데이터를 보낼 때, 한 라우터의 링크를 공유한다고 하자.
두 송신자가 같은 전송률을 가진다면, 수신측의 연결 당 처리량(per-connection throughput)은 그 절반이 된다. 특히, 공유 링크의 전송률이 R이라면, 송신자가 아무리 전송률을 높여도 각각 R/2 보다 더 높은 처리량을 얻을 수 없다.

각 송신자의 전송률이 R/2의 근처라면 처리량의 관점에서는 최대치인 R/2를 얻을 수 있지만, 지연 관점에서는 큐잉 지연이 커지므로 좋지 않다. R/2를 초과한다면, 큐잉 지연이 무제한으로 커진다.

3.6.1.2. 시나리오2: 2개의 송신자와 유한 버퍼를 갖는 하나의 라우터(Scenario 2: Two Senders and a Router with Finite Buffers)

이 시나리오에서는 버퍼가 가득 찼을 때, 도착하는 패킷들이 버려진다. 그리고 각 연결은 신뢰적이어서, 패킷이 버려지면 재전송된다.

패킷이 재전송될 수 있으므로, (1) 프로세스가 데이터를 소켓으로 보내는 전송률과 (2) 네트워크 안으로 세그먼트(원래 데이터와 재전송 데이터를 포함)를 송신하는 트랜스포트 계층에서의 전송률, 두 가지를 사용한다. 후자를 네트워크에 제공된 부하(offered load)라고도 부른다.

시나리오에 3가지 예가 있다. 먼저, 호스트가 라우터의 버퍼가 비어 있는지를 알 수 있어서, 패킷 손실이 절대로 발생하지 않는다고 가정하자. 이때는 (1)과 (2)가 같고, 평균 호스트 송신율은 R/2를 넘을 수 없다.

두번째 예는, 패킷이 손실된 것을 확실히 알았을 때(큰 타임아웃 사용), 재전송하는 경우이다. (2)가 0.5R 일 경우, 수신자 애플리케이션으로 전달되는 데이터의 전송률은 약 R/3이다. 그러므로 전송된 데이터의 0.5R 중 0.333R은 원래 데이터이고, 0.166R은 재전송 데이터이다. 즉, 송신자는 버퍼 오버플로 때문에 버려진 패킷을 보상하기 위해 재전송을 해야한다.

세번째 예는, 너무 일찍 타임아웃되는 바람에 패킷이 손실되지 않았지만, 큐에서 지연되고 있는 패킷을 재전송하는 경우이다. 이런 경우 원래의 데이터 패킷과 재전송 패킷 둘 다 수신자에게 도착한다. 물론 수신자는 재전송된 패킷을 버린다. 각 패킷이 두 번씩 전달되므로, (2)가 0.5R일 때 처리량은 0.25R이다. 즉, 커다란 지연으로 인한 불필요한 재전송은 라우터가 불필요한 복사본들을 전송하는데 링크 대역폭을 사용하는 원인이 된다.

3.6.1.3. 4개의 송신자와 유한 버퍼를 가지는 라우터, 그리고 멀티홉 경로(Scenario 3: Four Senders, Routers with Finite Buffers, and Multihop Paths)

제공된 부화가 어느 정도 증가함에 따라 처리량이 늘지만, 트래픽이 너무 많은 경우 처리량이 0이 된다.
처리량이 감소하는 원인은 네트워크가 수행한 헛된 작업의 양을 고려해보면 확실해진다. 패킷이 경로 상에서 버려질 때, 버려지는 지점까지 패킷을 전송하는 데 사용된 상위 라우터에서 사용된 용량은 헛된 것이 된다.

3.6.2. 혼잡제어에 대한 접근법(Approaches to Congestion Control)

네트워크 계층이 혼잡제어를 목적으로 트랜스포트 계층에게 어떤 도움을 제공하는지에 따라 혼잡제어 접근을 구별할 수 있다.

종단간의 혼잡제어: 네트워크 계층이 혼잡제어를 위해 트랜스포트 계층에게 어떤 지원도 제공하지 않는다. 종단 시스템이 관찰된 네트워크 행동에 기초항혀 혼잡의 존재를 추측해야 한다. 예를 들어, 타임아웃 또는 3중 중복확인이 나타날 때, TCP는 윈도우 크기를 줄인다.

네트워크 지원 혼잡제어: 네트워크 계층 구성요소는 혼잡 상와 관련하여 송신자에게 피드백을 제공한다. 예를 들어, ATM Available Bite Rate (ABR) 혼잡 제어에서, 라우터가 자신의 출력 링크(outgoint link)에 제공할 수 있는 전송률을 송신자에게 알려준다.

혼잡 정보는 전형적인 두 가지 방법 중 하나로 네트워크에서 송신자에게 피드백된다.

  1. 라우터가 송신자에게 초크 패킷(choke packet)을 보내 자신의 혼잡 상태를 알린다.
  2. 더 일반적인 방법은, 라우터가 흘러가는 패킷에 혼잡 상태를 기록(marks/updates)하는 것이다. 수신자가 이 기록된 패킷을 받으면, 혼잡 상황을 알게된다.

3.7.0. TCP 혼잡제어(TCP Congestion Control)

TCP는 네트워크 혼잡에 따라, 연결에 트래픽을 보내는 전송률을 각 송신자가 제한하도록 한다. (1) 어떻게 제한하고, (2) 혼잡을 어떻게 감지하고, (3) 어떤 알고리즘을 사용해 전송률을 변화시키는지 알아본다.

(1) 송신 측에서 동작하는 TCP 혼잡제어 메커니즘은 혼잡 윈도우(congestion window) 변수를 기록한다. cwnd로 표시되는 혼잡 윈도우는 전송률을 제한하는데, 특히 확인응답이 안된 데이터의 양이 cwnd와 rwnd의 최솟값을 초과하지 않도록 한다. 이 절에서는 혼잡제어에 집중하기 위해서, rwnd 값이 매우 커 수식의 우측 항이 cwnd라고 가정한다.

LastByteSent - LastByteAcked <= min(cwnd, rwnd)

다른 지연을 무시하고, 매 왕복시간(RTT) 마다 송신자가 cwndd 바이트만큼의 데이터를 전송한다면, 전송률을 cwnd/RTT 가 된다. 즉, cwnd의 값을 조절하여 송신자는 링크에 데이터를 전송하는 비율을 조절할 수 있다.

(2) 먼저, 타임아웃 또는 3개의 중복된 ACK를 받았을 때, TCP 송신자 측에 손실 이벤트(loss event)가 발생한다. 이때 송신자는 송신자와 수신자 사이의 경로상에 혼잡이 발생했음을 알게 된다.

손실 이벤트가 발생하지 않는 경우, TCP는 혼잡 윈도우 크기를 증가시키이 위해 확인응답을 사용한다. 확인응답이 늦게 오면 혼잡 윈도우는 상대적으로 낮은 속도로 증가하고, 빨리 오면 혼잡 윈도우는 더 빨리 증가될 것이다. TCP는 확인응답을 혼잡 윈도우의 크기 증가를 유발하는데 트리거(trigger) 또는 클록(clock)으로 사용하므로, TCP는 자체 클로킹(self-clocking)이라고 한다.

(3) TCP 송신자가 자신이 송신할 속도를 결정하기 위해 다음의 처리 원칙을 따른다. (3-1) 손실된 세그먼트는 혼잡을 의미하며, 이에 따라 TCP 전송률을 한 세그먼트를 손실했을 때 줄어져야 한다. (3-2) 확인응답은 수신자가 수신했다는 의미이므로, 이전에 확인응답되지 않은 세그먼트에 대해 ACK가 도착하면, 송신자는 전송률을 증가시킬 수 있다. (3-3) 밴드폭 탐색, 송신자는 혼잡이 발생하는 시점까지 전송률을 증가시키고, 그 시점 이후부터는 줄여 나간다. ACK들과 손실 이벤트는 묵시적 신호이며, 각 송신자들은 다른 송신자들과는 비동기적으로 로컬 정보에 근거해 동작한다.

3.7.0.1. 슬로 스타트(Slow Start)

슬로 스타트 상태에서는 cwnd값을 1MSS에서 시작하여, 한 세그먼트가 첫 번째 확인응답을 받을 때 마다 1MSS씩 증가시킨다. 그리고 손실 이벤트가 있을 경우, cwnd값을 1로 하고, 새로운 슬로 스타트를 시작한다.

또한 ssthresh(slow start threshold, 슬로 스타트 임계치) 변수를 cwnd/2(혼잡이 검출 되었을 때의 혼잡 윈도우의 절반)으로 정한다. 다음에 cwnd 값이 ssthresh와 같으면, TCP는 혼잡 회피 모드로 들어가 cwnd를 조심스럽게 증가시킨다.

3.7.0.2. 혼잡 회피(Congestion Avoidance)

혼잡 회피 모드에서는 매 RTT 마다 하나의 MSS만큼 cwnd 값을 증가시킨다. 예를 들어, MSS가 1,460바이트이고 cwnd가 14,600바이트일 때, 10개의 세그먼트가 한 RTT 내에 전송될 수 있다. 각 ACK는 1/10 MSS만큼씩 혼잡 윈도우를 증가시킨다. 10개 세그먼트의 ACK가 와야 혼잡 윈도우는 한 MSS만큼 커질 수 있다.

손실 이벤트 중 중복 ACK는 네트워크가 세그먼트를 계속 전달하고 있는 것이기에, 타임아웃보다는 덜 혼잡한 상태이다. 이 경우 TCP는 cwnd의 값을 반으로 하고, sshtresh값을 중복 ACK를 수신한 시점의 cwnd값의 반으로 한다. 이후 빠른 회복 상태로 들어간다.

3.7.0.3. 빠른 회복(Fast Recovery)

빠른 회복에서 cwnd값은 TCP를 빠른 회복 상태로 들어가게 했던 세그먼트에 대한 중복된 ACK를 수신할 때마다 1MSS만큼 증가된다. 빠른 회복은 권고 사항이지만 필수는 아니다.

손실 발생 시 혼잡 윈도우가 1MSS가 되는 TCP Tahoe, 빠른 회복을 사용하는 TCP Reno 등이 있다.

3.7.0.4. TCP 혼잡제어: 복습(TCP Congestion Control: Retrospective)

초기 슬로 스타트 기간을 무시하고, 손실 이벤트가 타임아웃이 아니라 중복 ACK라고 가정하면, TCP 혼잡제어는 매 RTT마다 1MSS씩 cwnd의 선형(가법적)증가와 중복 ACK 시 cwnd의 절반으로 구성된다.

이런 이유로 TCP 혼잡제어는 가법적 증가, 승법적 감소(additive-increase, multiplicative decrease, AIMD)의 혼잡제어 형식이라고도 불린다. 그리고 TCP Vegas 등 많은 변형이 있다.

3.7.0.5. TCP 처리율의 거시적 설명(Macroscopic Description of TCP Throughput)

슬로우 스타트 단계를 무시하고, 윈도우 크키가 w바이트, 왕복시간이 RTT초이면, TCP의 전송률은 대략 w/RTT이다. TCP는 손실 이벤트가 발생할 때(W)까지 RTT당 하나의 MSS만큼 w를 증가시킨다.

즉, 전송률이 W/RTT까지 증가했다가, 절반으로 줄어드는 것을 반복한다. TCP의 안정 상태(steady-state) 동작에 대한 간단한 거시 모델에서 연결의 평균 처리율은 0.75*W/RTT 이다.

3.7.0.6. 광대역 경로상의 TCP(TCP Over High-Bandwidth Paths)

TCP의 지속적인 개발은 애플리케이션에서 고속의 TCP 연결을 요구하기에 필요하다.

예를 들어, 1,500바이트 세그먼트와 100msec RTT를 갖는 TCP연결을 고려한다면, 앞에 있는 TCP 처리량 방식을 이용해서 10Gbps 처리량을 달성하기 위해서 평균 윈도우 크기는 83,333세그먼트가 필요하다.

오늘날의 TCP 혼잡제어 알고리즘은 2*10-10(50억 개의 세그먼트당 하나의 손실 이벤트)라는 세그먼트 손실 확률만을 허용(tolerate)한다.

3.7.1. 공평성(Fairness)

각각 다른 종단간의 경로를 갖지만, 모두 Rbps의 전송률인 병목 링크를 지나는 K개의 TCP 연결에서, 각 연결의 평균 전송률이 R/K에 가깝다면 혼잡 제어 메커니즘이 공평하다고 한다. 병목 링크란 각 연결 경로상의 모든 링크들은 혼잡하지 않고, 병목 링크보다 더 나은 전송 능력을 가지고 있다는 것이다.

많은 이상적인 가정(다른 UDP, TCP 연결 없음, 슬로 스타트 무시, 혼잡 회피 방식 사용)이 있을 때, TCP의 AIMD 알고리즘은 공평하다.

먼저 A부터 B로 즉, 두 호스트의 윈도우 크기가 증가한다.
그리고 B로부터 C로 즉, 패킷 손실로 인해 둘 다 절반(B와 원점의 중간)으로 줄어든다. 반복하다보면 두 호스트가 같은 대역폭을 갖게 된다.

3.7.1.1. 공평성과 UDP(Fairness and UDP)

많은 멀티미디어 애플리케이션은 혼잡제어가 없는 UDP를 사용한다. TCP 혼잡제어는 혼잡 증가에 대해서 전송률을 감소시키고, UDP 출발지는 그렇게 하지 않으므로 TCP 트래픽을 밀어낼 가능성이 있다. 오늘날 연구의 주요 분야는 UDP 트래픽으로 인해 인터넷이 마비되는 것을 방지하는 혼잡제어 방식을 개발하는 것이다.

3.7.1.2. 공평성과 병렬 TCP 연결(Fairness and Parallel TCP Connections)

TCP 기반 애플리케이션이 다중 병렬연결을 사용하면 공평성 문제가 생긴다. 예를 들어 웹 브라우저는 종종 웹 페이지에 다중 객체를 전송하기 위해 다중 병렬 TCP 연결을 사용한다. 한 애플리케이션이 전송률을 많이 쓸 가능성이 있다.

3.7.2. 명시적 혼잡 표시: 네트워크-지원 혼잡제어(Explicit Congestion Notification (ECN): Network-assisted Congestion Control)

최근에는 네트워크가 명시적으로 TCP 송신자와 수신자에게 혼잡을 알리는 IP와 TCP의 확장이 제안되었다. 네트워크 계층에서, IP 데이터 그램 헤더 필드 내에 두 비트가 ECN에 사용된다. ECN 비트는 라우터에 의해 사용되는데, 라우터가 경험하는 혼잡을 표시한다.

수신 TCP가 데이터그램을 통해 ECN 혼잡 표시를 수신하면, 세그먼트의 ECE 비트를 켜서 송신자에게 알려준다. 그러면 송신 TCP는 혼잡 윈도우를 반으로 줄이게 된다.

댓글남기기