Reference
- 내용전반: KOCW
Transport Layer는 Application Layer 하위 레이어로 좀 더 구체화된 레이어라 할 수 있다. Transport Layer의 프로토콜은 대표적으로 TCP와 UDP가 있다
Application Layer에서의 전송단위가 "메세지"였다면, Transport Layer의 전송단위는 "세그먼트
"라고 부른다. 세그먼트도 데이터와 헤더로 구성되는데, 데이터는 상위 레이어의 메시지가 그대로 들어가고 헤더에는 Transport Layer의 필드(대표적으로 포트넘버
)들이 추가된 형태가 된다
Transport Layer 프로토콜들이 기본적으로 지원하는 2가지 기능이 있다
일단 여기서는 Multiplexing에 대해서만 다루고 Error detection은 각 프로토콜에 대한 자세한 설명과 함께 다룰 것이다
사실 별거없다. 하나의 머신(=하나의 통신통로, 하나의 IP)에서 여러 소켓을 다루는 기능을 말한다. 이 기능을 지원하기 위해선 하나의 통로로 들어온 데이터가 어느 소켓으로 보내져야 하는지를 결정할 수 있어야 한다
TCP와 UDP가 이 기능을 지원하는 방법이 (완전히) 다르다
UDP는 목적지 IP주소+포트넘버
만을 따져 목적지 소켓을 결정한다. 즉, 목적지 IP주소+포트넘버가 같은 데이터는 모두 동일한 소켓으로 향한다
따라서 UDP 소켓을 사용하는 경우 여러 소켓이 동일한 포트넘버를 사용할 수 없다. 그 이유는 UDP는 커넥션을 만들지 않아서 1대1 관계가 아니기 때문이다
TCP는 목적지 IP주소+포트넘버
뿐만 아니라 출발지 IP주소+포트넘버
도 함께 따져 목적지 소켓을 결정한다. 위 그림에서 P4,P5,P6 세 프로세스의 소켓들은 모두 동일한 IP주소+포트넘버를 사용 중이지만 출발지 IP주소+포트넘버를 따져 어느 소켓으로 가야할지를 결정할 수 있다
따라서 TCP 소켓을 사용하는 경우 여러 프로세스가 동일한 포트넘버를 사용할 수도 있다. 그 이유는 TCP는 소켓 간 커넥션을 생성하여 1대1 관계를 형성하기 때문이다
❗️NOTE❗️
하나의 프로세스가 충분히 여러 소켓을 가질 수도 있다
UDP는 Transport Layer가 공통적으로 지원하는 2가지 기능만을 지원한다
어떤 프로토콜이든 데이터부와 헤더부로 구성된다. 그리고 헤더부에 어떤 필드들이 붙는지를 아는 것이 그 프로토콜을 이해하는 것과 동일하다고 볼 수 있다. 왜냐하면 프토토콜이 어떤 기능을 제공하려면 부가 정보가 필요한데 그게 헤더필드에 적히기 때문이다
UDP 세그먼트는 위 그림과 같은 구성으로 이루어진다. 데이터부는 메시지가 되고, 헤더부는 단지 4개의 필드를 가진다. "단지"라는 표현을 쓴 이유는 UDP는 기능이 적어서 4개인 반면, TCP는 기능이 많아서 필드도 훨씬 많기 때문이다
TCP는 UDP와 달리 Reliable한 데이터 전송을 지원하는 프로토콜이다. 본격적으로 TCP에 대해 알아보기 전에 Reliable한 데이터 전송이 어떻게 가능한건지 알아보자
우선 Transport Layer에서 Reliable을 보장한다는 것은, 반대편 Transport까지 무사히 전달함을 의미한다. 하지만 하위 Layer인 Network/Link Layer들에서 별의별 일이 다 일어나는데 어떻게 이걸 Transport에서 보장한다는 걸까?
사실 발생가능한 문제를 정의해보면 패킷이 유실되거나 패킷에 에러가 발생하거나 2가지 뿐이다
🔘 기본기능
🔘 추가기능
Feedback checksum
Feedback에 에러가 발생하는 경우 3가지 기본기능만으로는 대처가 불가하다. 그래서 Feedback에도 checksum
을 붙혀 Error detection이 가능케 한다. checksum으로 확인해보니 Feedback에 문제가 생긴 것이라면 NAK으로 간주하고 데이터를 재전송한다
SEQ 넘버
또 문제가 있다. 데이터를 재전송했는데 receiver 입장에선 이게 교체용 데이터인지, 추가 데이터인지 구분이 불가하다. 그래서 각 데이터에 SEQ 넘버
를 붙혀 구분하게 한다. 같은 SEQ 넘버의 패킷이 또 들어왔다면 교체용임을 인지하여, 기존 데이터는 버리고 새로 들어온 데이터로 교체한다
❗️SEQ 넘버는 몇 bit으로 설계할까?
직관적으론 모든 패킷을 순차적으로 붙이면 편하겠지만, 우리는 헤더의 크기를 최소화할 의무가 있다. 사실 지금의 메커니즘대로라면1bit
만 있으면 된다. 홀/짝 개념으로 0,1을 번갈아가며 쓰면 되기 때문이다. 아래 그림을 참고
❗️얼마나 기다려야 할까?
사실 정답이 없는 문제다. 시간이 짧으면, 유실 대응은 빠르지만 정말 유실이 발생한건지 어쩌다 늦는건지 판단이 어렵다. 결국 중복 전송이 쉽게 발생하고 이는 네트워크 오버헤드가 된다. 시간이 길면, 중복 전송은 줄일 수 있으나 유실 대응이 느리다
여기서 다루는건 타이머가 끝임ㅋ 아래 그림은 예시를 보여준다. 놀랍게도 타이머에 의해 중복 전송이 발생하더라도 네트워크 오버헤드 정도만 유발될뿐 SEQ 넘버 덕에 메커니즘은 꼬이지 않고 잘 동작한다
사실 RDT 메커니즘은 실제로 사용하기엔 너무 단순하다. 패킷을 하나 보내면 ACK가 날 때까지 다른 패킷을 전송할 수 없다. 신뢰성은 확보했지만 속도가 너무 느리다. 그래서 실제 TCP는 한 번에 하나의 패킷만 처리하는게 아니라, 아래 그림처럼 데이터와 ACK 패킷을 들이붓는 파이프라인 구조를 보인다
아래 그림은 3개 패킷을 파이프라이닝을 했을 때의 utilization(작업시간/전체시간)을 계산한 것이다. 거리가 멀수록 많은 패킷을 파이프라이닝해야 효율이 확보된다
Before | After |
---|---|
이렇게 파이프라이닝을 위해 2가지 접근법이 제안된다. 이것들은 접근법일뿐 실제 TCP는 또 다른 방식으로 동작함에 유의하자
한 번에 얼만큼의 패킷을 보낼 것이냐에 대한 개념으로 window가 등장한다. window만큼의 패킷을 Feedback없이 한 번에 보낼 수 있다. 패킷 타이머가 timeout되면 현재 window의 모든 패킷을 재전송한다. 아래 예시를 통해 구체적으로 과정을 알아보자
🔘 구체적인 과정
이처럼 window size N만큼 돌아와서 재전송한다고 해서 Go-back N이라는 이름이 붙었다
참고
Go-back N에서는 window size만큼 재전송이 가능해야 한다. 즉, 그만큼의 데이터를 버퍼에 가지고 있을 수 있어야 한다
Go-back N은 개선의 여지가 많은 메커니즘이다. 현실에선 window size가 예시처럼 4개가 아니라 매우 클 수 있다. Go-back N을 개선하는 메커니즘으로 Selective Repeat이 있다
이름에서부터 느껴지듯 선택적으로 재전송하는 메커니즘이다. 동일하게 window 개념이 존재한다. 단, 여기서의 ACK의 의미는 Go-back N처럼 누적형이 아니다. 그리고 receiver가 버퍼관리를 해야한다. 위 예시와 동일한 상황에서 어떻게 다른지 알아보자
receiver의 Transport Layer는 버퍼를 두어 순차적으로 ACK가 도착한 패킷만 Application Layer로 올려보낸다
🔘 구체적인 과정
🔘 SEQ 넘버는 몇 bit?
SEQ 넘버는 windowSize의 2배는 되어야 한다. 위 예시는 window size가 3일 때, SEQ 넘버가 4개로 부족한 경우에서 어떤 문제가 생기는지를 나타낸다
🔘 TCP는 이걸 쓰나?
그렇진 않다. 여러 방식의 장점만을 취한 형태를 사용한다. 지금까지 설명한 방식들이 이론상으로는 말이 되지만 실제로는 수많은 프로세스와 매우 큰 windowSize 덕에 패킷 하나하나에 타이머를 전부 관리하는건 오버헤드가 엄청나다. TCP는 window 통째로 타이머 하나를 쓰고 ACK도 누적형을 쓴다. 자세한건 TCP 섹션에서