[네트워크/Network] TCP는 어떻게 신뢰적인 데이터 전달을 할까?

kindof

·

2021. 9. 13. 20:47

👀 0. 들어가면서

이번 시간에는 트랜스포트 계층의 프로토콜은 TCP에 대해 이야기해보려고 합니다. UDP에 대한 정리는 아래 포스팅에 있으니 참고해주세요.

 

 

[네트워크/Network] 비연결형 트랜스포트 UDP 정리

💡0. 들어가면서 이전 포스팅에서 OSI 7계층에 대해 정리를 했었는데요. 트랜스포트 계층의 기본적인 역할은 네트워크 계층과 애플리케이션 레벨 프로세스 간의 데이터를 넘겨주기 위해서 다중

studyandwrite.tistory.com

 

한편, TCP는 신뢰적인 데이터 전송, 혼잡 제어 등 여러가지 기능을 제공하는 프로토콜이기 때문에 설명할 내용이 굉장히 많습니다. 그래서 앞으로 몇 개의 포스팅에 걸쳐 이러한 내용들을 다뤄보도록 하겠습니다.

 

우선, 이번 포스팅에서는 TCP의 가장 기본적이면서도 중요한 '신뢰적인 데이터 전달' 메커니즘에 대해 살펴보도록 하겠습니다.

 


 

 

📒 1. TCP - 연결지향형 트랜스포트

자, 그럼 이제 TCP 프로토콜에 대해 알아보겠습니다. 우선 TCP의 개념에 대해 살펴보겠습니다.

 

TCP는 애플리케이션 프로세스가 데이터를 다른 프로세스에게 보내기 전에, 두 프로세스가 서로 "핸드셰이크"를 해야하므로 연결지향형인 특징을 갖습니다. 

 

그러나 TCP 프로토콜은 종단 시스템(End-point)에서만 동작하고, 중간의 네트워크 요소(라우터나 브릿지 등)에서는 동작하지 않기 때문에 중간에 네트워크 요소들은 TCP 연결 상태를 유지하지 않습니다. 중간 라우터들은 TCP 연결을 의식하지 않고 그냥 지나다니는 데이터그램만을 볼 뿐이죠. 

 

*핸드셰이크에 대한 내용은 아래 포스팅에 정리되어 있으니, 참고해주세요.

 

[네트워크/Network] TCP 연결 관리와 2, 3, 4 Way Handshaking(핸드쉐이킹)에 대해

📋 1. 오버뷰(Overview) TCP는 애플리케이션 프로세스가 데이터를 다른 프로세스에게 보내기 전에, 두 프로세스가 서로 "핸드셰이크"를 먼저 해야 한다는 것에서부터 연결지향형(connection-oriented)이

studyandwrite.tistory.com

 

한편, TCP 연결은 항상 단일 송신자와 단일 수신자 사이의 점대점(point-to-point)입니다. 단일 송신 동작으로 한 송신자가 여러 수신자에게 데이터를 전송하는 멀티캐스팅은 불가능합니다.

 

TCP는 TCP 헤더와 클라이언트 데이터를 하나로 만들어 TCP 세그먼트를 형성합니다. 세그먼트는 네트워크 계층에 전달되며, 네트워크 계층 IP 데이터그램 안에 각각 캡슐화됩니다.

 

이 때, TCP 세그먼트의 크기는 최대 세그먼트 크기(Maximum segment size, MSS)로 제한되는데, MSS는 일반적으로 로컬 송신 호스트에 의해 전송될 수 있는 가장 큰 링크 계층 프레임의 길이인 최대 전송 단위(Maximum transmission unit, MTU)에 의해 결정됩니다.

 

따라서 TCP가 웹 문서의 이미지와 같은 큰 파일을 전송할 때는 파일을 MSS크기의 파일 여러개로 쪼개서 보내게 됩니다.

 

 

📬 2. TCP 세그먼트와 신뢰적인 데이터 전송

아래 그림은 TCP 세그먼트의 구조입니다.

 

TCP 세그먼트 구조

TCP는 UDP처럼 헤더에 상위 계층  애플리케이션로부터 다중화와 역다중화를 하는 데 사용하는 출발지와 목적지 포트 번호를 기록합니다.

 

그 아래에는 순서번호(Sequence Number)확인응답번호(Acknowlege Number)가 있는데, 이 부분이 신뢰적인 데이터 전송 서비스 구현에서 중요한 역할을 하게 됩니다. 한 번 살펴볼까요?

 

TCP 세그먼트로 분할되는 파일 데이터

위의 2-1. TCP에 대한 설명에서 TCP는 큰 파일을 전송할 때 MSS크기의 파일 여러개로 쪼개서 전송한다고 이야기했습니다.

 

그런데 한편으로 TCP는 데이터를 구조화되어 있지 않고, 단지 순서대로 정렬된 바이트 스트림으로 봅니다. 그래서 TCP의 "순서번호는 전송된 세그먼트를 기준으로 번호를 부여하는 것이 아닌 전송된 바이트 스트림에 대한 번호를 부여"하게 됩니다. 그리고 이를 통해 유추해보면, "각 세그먼트에 대한 순서번호는 세그먼트의 첫 번째 바이트의 바이트 스트림 번호"라는 것을 알 수 있죠.

 

갑자기 바이트 스트림, 순서 번호라는 말을 하게 되니 무슨 말인지 헷갈릴 수 있습니다. 천천히 다시 설명해보겠습니다.

 

예를 들어 호스트 A에서 호스트 B로 데이터 스트림을 전송한다고 해봅시다. 데이터 스트림은 500,000바이트로 구성된 파일이고, MSS는 현재 1,000바이트, 데이터 스트림의 첫 번째 바이트는 0이라고 하겠습니다.

 

위 상황에서 TCP는 데이터 스트림으로부터 500개의 세그먼트를 구성할 것입니다. 첫 번째 세그먼트의 순서번호는 0이고, 두 번째 세그먼트의 순서번호는 1,000이 되겠죠? 그리고 각각의 순서번호는 적절한 TCP 세그먼트 헤더 내부의 순서번호 필드에 삽입되어 보내집니다.

 

한편 TCP는 호스트 A가 호스트 B로 데이터를 송신하는 동안에 호스트 B로부터 데이터를 수신하는 전이중 방식이기 때문에, 호스트 B로부터 도착한 세그먼트는 B로부터 A로 들어온 데이터에 대한 순서 번호를 갖습니다. 그리고 이 때 호스트 A가 자신의 세그먼트에 삽입하는 확인응답번호는 호스트 A가 호스트 B로부터 기대하는 다음 바이트의 순서번호입니다.

 

무슨 말이냐고요?

 

예를 들어 호스트 A가 B로부터 0~535까지 번호가 붙은 모든 바이트를 수신했다고 가정해봅시다. 그리고 호스트 B로 세그먼트를 송신하려고 합니다. 이 때 호스트 A는 호스트 B의 데이터 스트림에서 536번째 바이트와 그 다음에 오는 바이트들을 기다리고 있겠죠? 그래서 호스트 A는 세그먼트의 확인응답번호 필드에 536을 삽입하고 B로 송신합니다.

 

또 다른 예로, 호스트 A가 호스트 B로부터 0~535의 바이트를 포함하는 세그먼트와 900~1,000바이트를 포함하는 세그먼트를 수신했다고 해봅시다. 그러면 호스트 A는 현재 536~899 바이트를 아직 수신하지 않은 상태겠죠? 그래서 B에 대한 A의 다음 세그먼트는 확인응답번호 필드에 536을 가질 것입니다. TCP는 스트림에서 첫 번째 잃어버린 바이트까지의 바이트들까지만 확인하기 때문에, TCP는 누적 확인응답(cumulative acknowledgment)을 제공한다고 합니다.

 

.

.

.

 

위에서 설명한 순서번호 필드와 확인응답번호 필드가 TCP가 손실 세그먼트를 발견하기 위해 타임아웃/재전송 메커니즘을 사용할 수 있게 합니다. TCP가 세그먼트를 IP로 넘길 때 단일 타이머가 작동되고, 이 타이머에 대한 만료 주기(TimeoutInterval)가 되면 타임아웃을 일으킨 세그먼트를 재전송하는 것입니다. 

 

손실된 확인응답에 따른 재전송

타임아웃과 재전송 시나리오에 대해 구체적으로 들여다보면 여러가지가 있을 수 있겠지만, 이번 글에서는 순서번호와 확인응답번호를 통해 타임아웃/재전송 매커니즘이 실현되고 이를 통해 신뢰적인 데이터 전송이 가능해진다는 것을 이해하면 됩니다.

 

 

🗒 3. 나가면서

이렇게 오늘은 TCP와 UDP에 대한 간략한 설명과 TCP가 왜 연결지향형이며 신뢰적인 데이터 전달을 하는지 알아보았습니다.

 

아래 그림이 재밌어서 가져와봤는데 이 그림으로 위 내용을 정리해보면 좋을 것 같습니다.

TCP와 UDP 요약