신뢰적인 데이터 전송
비신뢰적인 인터넷의 네트워크 계층(IP 서비스)
- 인터넷 프로토콜은 데이터그램 전달을 보장 X
- 데이터그램이 순서대로 전달되는 것도 보장 X
- 데이터그램에 포함된 데이터의 무결성(intergrity)을 보장 X
- 비트가 손상될 수도 있다.
- 비트가 손상될 수도 있다.
- IP 서비스에서 데이터그램은 라우터의 버퍼를 오버플로 상태로 만들 수 있음
- 트랜스포트 계층의 세그먼트가 IP 데이터그램에 의해 네트워크 상에서 운반됨
→ 트랜스포트 계층의 세그먼트도 이러한 문제를 겪을 수 있음
TCP의 신뢰적인 데이터 전송 서비스
- TCP는 IP의 비신뢰적인 최선형 서비스에서 신뢰적인 데이터 전송 서비스를 제공
- TCP 타이머 관리 절차에서는 단일 재전송 타이머 사용을 권장한다.
- 전송됐지만 아직 확인응답받지 못한 세그먼트와 개별적인 타이머가 한쌍인 경우
→ 이론상으론 좋아도, 타이머 관리는 상당한 오버헤드를 발생시킨다. - 이 글에서는 단일 타이머 사용을 전제로 한다.
- 전송됐지만 아직 확인응답받지 못한 세그먼트와 개별적인 타이머가 한쌍인 경우
신뢰적인 데이터 전송 서비스의 사용
- 프로세스가 자신의 수신 버퍼로부터 읽은 데이터 스트림이 손상/손실/중복이 없다는 것을 보장
- 자신의 수신 버퍼로부터 읽은 데이터 스트림이 순서가 유지된다는 것을 보장한다.
- 바이트 스트림은 송신자가 전송한 것과 같은 바이트 스트림
→ 신뢰적인 데이터 전송의 원칙을 모두 포함한다.
TCP 신뢰적인 데이터 전송과 관련된 3가지 주요 이벤트
/*
송신자가 TCP 흐름이나, 혼잡 제어로 인해 제한받지 않는다고 가정하고,
위의 데이터의 크기는 MSS보다 작고, 데이터 전송한 한 방향이라고 가정한다.
*/
NextSeqNum=InitialSeqNumber
SendBase=InitialSeqNumber
loop (forever) {
switch(event)
event: data received from application above
create TCP segment with sequence number NextSeqNum
if(timer currently not running)
start timer
pass segment to IP
NextSeqNum=NextSeqNum+length(data)
break;
event: timer timeout
retransmit not-yet-acknowledged segment with
smallest sequence number
start timer
break;
event: ACK received, with ACK field value of y
if(y > SendBase) {
SendBase = y
if(there are currently any not-yet-acknowledged segments)
start timer
}
break;
} /* 무한 루프 종료 */
- 가정
- 호스트 A에서 B로 데이터가 오직 한 방향으로만 보내짐
- 호스트 A가 큰 파일을 전송
- 해당 코드에서 데이터 전송/재전송에 관련된 세 가지 주요 이벤트가 있음
→ 상위 애플리케이션으로부터 수신된 데이터, 타이머 타임아웃, ACK 수신
첫 번째 주요 이벤트 - 상위 애플리케이션으로부터 수신된 데이터
- TCP는 애플리케이션으로부터 데이터를 받음
- 세그먼트는 받은 데이터를 캡슐화하고 IP에게 해당 세그먼트를 넘김
- 각 세그먼트는 해당 세그먼트의 순서 번호 포함한다.
- 각 세그먼트는 해당 세그먼트의 순서 번호 포함한다.
- 타이머가 이미 다른 세그먼트에 대해 실행 중이 아닌 경우
→ TCP는 이 세그먼트를 IP로 넘길 때 타이머를 시작
- 이 타이머의 만료 주기는
TimeoutInterval
- 이 타이머의 만료 주기는
두 번째 주요 이벤트 - 타임아웃
- TCP는 타임아웃 이벤트에 대해 타임아웃을 일으킨 세그먼트를 재전송하여 응답
- TCP의 타이머를 재시작
세 번째 주요 이벤트 - 수신자로부터의 수신 확인응답 세그먼트(ACK) 수신
- 여기서 수신자는 다양한 ACK 필드값을 가진 세그먼트를 뜻함
- 이 이벤트가 발생하면 TCP 변수
SendBase
와 ACK 값 y를 비교SendBase
: 수신 확인응답이 확인되지 않은 가장 오래된 바이트의 순서 번호SendBase-1
은 수신자에게서 차례대로 수신됐음을 알리는 마지막 바이트 순서 번호
- TCP는 누적 확인응답을 사용
- y는 y 바이트 이전의 모든 바이트의 수신 확인
y > SendBase
인 경우- ACK는 이전에 확인응답 안 된 하나 이상의 세그먼트들을 확인
→ 송신자는 자신의 SendBase 변수를 갱신 - 또한 아직 확인응답 안 된 세그먼트들이 존재한다면 타이머를 재시작
- ACK는 이전에 확인응답 안 된 하나 이상의 세그먼트들을 확인
신뢰적인 데이터 전송이 작동하는 과정 - 시나리오 1
- 가정
- 긍정 확인응답이 손실됐을 때
- 호스트 A가 호스트 B에게 하나의 세그먼트를 보냄
- 이 세그먼트는 순서 번호 92와 8바이트의 데이터를 포함한다고 가정
- 과정
- 호스트 A가 해당 세그먼트 전송 후
→ 호스트 B로부터 긍정 확인응답 번호 100을 가진 세그먼트를 기다림 - B가 수신하고 A로 긍정 확인응답 번호 100 (ACK = 100) 전송
- 이때 ACK= 100이 손실된다고 가정
- 타임아웃이 발생하고, 호스트 A는 같은 세그먼트를 B에게 재전송
- 호스트 B가 재전송 세그먼트를 수신했을 때, 이미 수신된 데이터임을 알 수 있음
← 재전송된 세그먼트가 포함하고 있는 순서 번호를 통해 알 수 있기 때문 - 호스트 B는 이미 수신된 데이터이므로, 재송신된 세그먼트의 바이트를 버림
신뢰적인 데이터 전송이 작동하는 과정 - 시나리오 2
- 가정
- 호스트 A가 연속해서 2개의 세그먼트를 전송
- 첫 번째 세그먼트 → 순서 번호 92와 8바이트의 데이터를 가짐
- 두 번째 세그먼트 → 순서 번호 100과 20바이트의 데이터를 가짐
- 두 세그먼트가 모두 호스트 B에 무사히 도착한다고 가정
- 호스트 A에서는 타임아웃 이전에 어떠한 긍정 확인응답도 수신하지 못한다고 가정
- 호스트 A가 연속해서 2개의 세그먼트를 전송
- 과정
- B는 각각의 세그먼트에 대해 2개의 개별적인 긍정 확인응답을 전달
- 첫 번째 → 긍정 확인응답 번호 100(ACK = 100)을 가짐
- 두 번째 → 확인응답 번호 120(ACK = 120)
- 호스트 A에서 타임아웃 이벤트가 발생
→ 순서 번호 92로 첫 번째 세그먼트를 재전송하고 타이머를 재시작- 새로운 타임아웃이 끝나기 전까진 두 번째 세그먼트의 ACK = 120가 도착해도 재전송 X
- B는 각각의 세그먼트에 대해 2개의 개별적인 긍정 확인응답을 전달
신뢰적인 데이터 전송이 작동하는 과정 - 시나리오 3
- 가정
- 호스트 A가 2개의 세그먼트를 전송한다고 가정
- 첫 번째 세그먼트의 긍정 확인응답이 네트워크에서 분실된다고 가정
- 과정
- 첫 번째 세그먼트의 긍정 확인응답이 네트워크에서 분실
- 첫 번째 세그먼트의 타임아웃 전에 호스트 A가 ACK=120을 수신
→ 호스트 B가 119 바이트까지 모든 데이터를 수신했음을 알게 됨 - 호스트 A는 두 세그먼트 중 어떠한 것도 전송하지 않는다.
- 누적 확인응답은 첫 번째 세그먼트의 재전송을 방지한다.
빠른 재전송
타임아웃이 유발하는 재전송 문제
- 타임아웃의 주기가 때때로 비교적 길다는 점
- 긴 타임아웃 주기는 잃어버린 패킷을 다시 보내기 전에 송신자를 오래 기다리게 한다.
→ 긴 타임아웃 주기는 종단 간의 지연을 증가시킨다. - 다행히, 송신자는 종종
중복 ACK
에 의한 타임아웃이 일어나기 전에 패킷 손실을 발견중복 ACK
: 송신자가 이미 이전에 받은 확인응답에 대한 재확인응답 세그먼트 ACK
수신자가 중복 ACK를 보내는 이유
- TCP 수신자가 기다리는 다음 것보다 더 큰 순서 번호를 가진 세그먼트를 받은 경우
→ TCP 수신자는 그 데이터 스트림에서의 간격(손실 세그먼트)을 찾아냄
- 여기서의 간격은 세그먼트 손실이나, 순서가 바뀐 결과일 수도 있다.
- 여기서의 간격은 세그먼트 손실이나, 순서가 바뀐 결과일 수도 있다.
- TCP는 부정 확인응답을 사용 X
→ 수신자는 마지막으로 수신된 순차적인 바이트를 갖는 데이터를 다시 확인응답(즉, 중복 ACK 생성)
- 수신자가 순서가 뒤바뀐 세그먼트를 버리지 않는 경우라고 가정
중복 ACK에 대한 송신자의 반응
- 송신자는 많은 양의 세그먼트를 연속적으로 보낼 수 있음
→ 하나의 세그먼트를 잃어버린다면 많은 연속적인 중복 ACK 존재 가능 - TCP 송신자가 같은 데이터에 대해 3개의 중복 확인응답을 수신
→ ACK 된 세그먼트의 다음 3개의 세그먼트가 분실되었음을 의미
- 3개의 중복 ACK를 수신할 때, TCP는
빠른 재전송
빠른 재전송
: 세그먼트의 타이머가 만료되기 전에 손실 세그먼트를 재전송
- 3개의 중복 ACK를 수신할 때, TCP는
- 두 번째 세그먼트를 잃어버린 경우, 타이머가 만료되기 전에 재전송됨
event : ACK received, with ACK field value of y
if(y > SendBase) {
SendBase = y
if(these are currently any not yet acknowledged segments)
start timer
}
else { /* 이미 ACK된 세그먼트에 대한 중복 ACK*/
increment number of duplicate ACKs received for y
if(number of duplicate ACKs received for y == 3)
/* TCP 빠른 재전송 */
resend segment with sequence number y
}
break;
TCP는 GBN인가? SR인가?
- TCP 확인응답은 누적되고 올바르게 수신된다.
- 순서가 잘못된 세그먼트는 수신자가 개별적으로 ACK를 받지 않는다.
- TCP 송신자는
SendBase
와NextSeqNum를
유지해야 한다.SendBase
: 전송했지만 확인응답 안 된 바이트의 가장 작은 순서 번호NextSeqNum
: 전송될 다음 바이트의 순서 번호
TCP와 GBN의 차이점
- TCP는 올바르게 수신되었지만 순서가 바뀐 세그먼트들을 버퍼링 한다.
- 예시
- 가정
- 송신자가 세그먼트 1,2…N을 전송하고 수신 측에 오류 없이 순서대로 도달
- 패킷 n < N에 대한 긍정 확인응답이 손실됐음
- 하지만, 나머지 N-1개의 긍정 확인응답들은 타임아웃 전에 송신 측에 도달
- GBN의 동작
- 패킷 n과 n+1, n+2 … N 모두를 재전송한다.
- 패킷 n과 n+1, n+2 … N 모두를 재전송한다.
- TCP의 동작
- 세그먼트 n 하나만을 재전송한다.
- 세그먼트 n에 대한 타임아웃 전에 세그먼트 n+1에 대한 긍정 확인응답이 도착할 경우
→ 세그먼트 재전송 X
- 가정
선택적 확인응답(selective acknowledgement)
- TCP에 수정 제안된 것
- TCP 수신자가 ‘순서가 틀린’ 세그먼트에 대해 선택적으로 확인응답을 하게 한다.
- 기존에는 올바르게 수신된 ‘순서가 맞는’ 세그먼트에 대해 확인응답하였음
- 기존에는 올바르게 수신된 ‘순서가 맞는’ 세그먼트에 대해 확인응답하였음
- 선택적 재전송과 결합했을 경우
→ TCP는 원래의 SR 프로토콜과 유사
결론
- TCP의 오류 복구 메커니즘은 GBN과 SR 프로토콜의 혼합으로 분류하는 것이 적당