트랜스포트 계층의 데이터를 세그먼트로 통일해서 적는다.
UDP는 비신뢰적이고 비연결형 서비스이다.
UDP 헤더를 확인하며 프로토콜을 이해해보자.
{출발지 포트, 도착지 포트, 길이, 체크섬}
UDP의 헤더는 2바이트로 구성된 4개의 필드가 전부고,
이 필드들을 이용해서 2가지 {다중화/역다중화, 오류 검출}
기능만을 제공한다.
하나씩 살펴보자.
다중화와 역다중화의 개념은 앞서 3-1에서 알아봤으니 간단히 식별 방법만 언급하고 넘어간다.
UDP 소켓은 {도착지 IP주소, 도착지 포트번호}
에 의해 식별된다.
출발지 IP주소
나 출발지 포트
가 다르더라도 도착지 IP주소
와 도착지 포트번호
가 같다면
같은 도착지 소켓을 통해 같은 프로세스로 향하게 된다.
(포트는 16비트이기 때문에 0 ~ 65535의 범위를 갖는다.)
"어짜피 UDP 소켓이 도착지 IP주소
와 도착지 포트번호
로 식별된다면 출발지 포트는 왜 필요한가"라는 의문이 들 수 있다.
이 출발지 포트는 회신주소이다.
그림과 같이 UDP 서버에서 패킷을 받았을 때 응답을 주려면 이 출발지 포트가 필요하다.
길이 필드는 헤더를 포함하는 UDP 세그먼트의 바이트 단위의 길이를 나타낸다.
체크섬 필드는 오류검출을 위해서 존재한다.
체크섬 필드는 다음과 같은 과정으로 만들어진다.
UDP 패킷 발신자
1. UDP 세그먼트 안에 있는 모든 16비트 워드를 합친다.
2. 1의 보수를 취한다. (비트 반전)
3. 이 과정의 결과를 체크섬 필드로 세팅한다.
UDP 패킷 수신자
1. 전송받은 UDP 세그먼트 안에 있는 모든 16비트 워드를 합친다.
2. 합친 결과와 전송받은 UDP 세그먼트의 체크섬 필드를 합친다.
3. 이 과정의 결과가1111111111111111
이 아니라면 패킷에 오류가 발생한 것이다.
UDP는 오류 검사를 제공하지만 오류를 회복하기 위한 어떤 일도 하지 않는다.
그냥 버리거나, 경고와 함께 애플리케이션에 넘겨주기도 한다.
16비트이지만 간단하게 4비트로 예시를 들어본다.
1010
, 1100
, 0111
가 전송될 것이다.
UDP 패킷 발신자
1. 합산 결과 =>1101
2. 반전 결과 =>0010
3.0010
을 체크섬 필드로 세팅
UDP 패킷 수신자
1. 합산 결과 =>1101
2. 결과 =>1101
+0010
=>1111
3. 패킷 오류 없음.
UDP는 트랜스포트 계층 프로토콜이 할 수 있는 최소 기능으로 동작한다.
UDP는 다중화/역다중화 기능과 간단한 오류 검출을 추가적인 기능을 제공하지 않는다.
UDP를 선택한다는 것은 사실상 네트워크 계층의 IP와 직접 통신하는 것과 같다.
(UDP는 핸드쉐이크를 하지 않는다. -> 핸드쉐이크는 TCP에서 살펴본다.)
UDP의 기능
1. 다중화/역다중화
2. 오류 검출
지금까지 UDP의 헤더와 역할을 알아봤다.
신뢰적이고 연결지향형 서비스인 TCP에 반해
비신뢰적이고 비연결형 서비스인 UDP가 부정적으로 느껴질 수 있다.
그럼 많은 애플리케이션에서 TCP가 항상 선호될까? 그렇지 않다.
왜 애플리케이션에서 TCP가 아닌 UDP도 사용하는지 알아보자.
UDP가 사용되는 이유를 알기 전에 TCP의 몇가지 특징만 알아두자.
TCP의 여러 특징 중 몇 가지 특징만 아주 간단하게 언급할 것이다.
나중에 쓸 글에서 자세히 알아볼 내용이기 때문에 그렇구나 하고 넘어가면 된다.
연결지향형 서비스인 TCP는 두 종단 시스템의 연결을 유지하기위해서 3-way, 4-way Handshake를 사용한다.
3-way Handshake를 통해 통신을 시작하기전 각자의 송수신 버퍼를 동기화하고,
4-way HandShake를 통해 통신을 안전하게 종료하는 것이다.
이로 인해 UDP와 달리 TCP는 연결을 시작할 때와 종료할 때 사전작업이 필요하다.
신뢰적인 TCP는 네트워크 상황이 혼잡하다고 판단되면 전송률(전송속도)을 낮춰서 네트워크의 혼잡도를 낮추려하는데 이 메커니즘을 혼잡제어라 부른다.
(+ TCP는 네트워크 혼잡도를 낮추기 위해 전송률을 점차 높혀나가는 식으로 전송한다.)
왜 낮추는지? 어떻게 혼잡도를 판단하는지? 등등의 궁금함이 있겠지만
지금은 우선 넘어가고 "TCP는 네트워크 상황이 혼잡하다면 전송률을 낮추고 전송률을 점차 높혀나간다."라고만 알고있자.
뒤에 TCP를 다루는 글에서 자세히 살펴볼 것이다.
UDP의 경우 TCP 처럼 혼잡제어 방식을 사용하지 않기 때문에 전송률의 제한없이 보낼 수 있다.
전송률의 제한없이 보낸다는게 빠르다는 것을 의미하는 것은 아니다.
이전 글 1-2에서 언급한 것 처럼 혼잡한 네트워크에서 많은 패킷을 보내게 되면
결국 라우터의 큐가 감당할 수 있는 양보다 많은 패킷이 들어오면서 패킷이 손실된다.
결국 수신자는 해당 패킷을 못받게 된다.
그래서 혼잡제어가 없으므로 제한없이 보낸다는 것이 수신자가 빠르게 패킷을 받을 수 있다는 것을 의미하는게 아니다.
TCP는 전송을 시작하기 전에 3-way Handshake를 사용한다.
이로 인해 애플리케이션 데이터 전송에 지연이 발생한다.
하지만 UDP는 이런 사전 작업없이 바로 패킷을 보낼 수 있다.
(이 부분이 DNS가 UDP를 사용하는 일반적인 이유이다.)
TCP를 사용하면 클라이언트와 서버는 각각 어떤 패킷을 받았는지 어떤 패킷을 받지 않았는지 버퍼를 통해 동기화해야 각자의 패킷을 유실없이 받을 수 있다.
하지만 UDP는 이렇지 않다. 그냥 보내면된다.
이러한 이유 때문에 서버가 TCP보다 UDP에서 동작할 때 좀 더 많은 액티브 클라이언트를 수용할 수 있다.
TCP의 경우 20바이트의 헤더 크기를 가진다.
하지만 UDP는 8바이트의 헤더 크기를 갖는다.
인터넷 전화, 온라인 게임같은 경우 몇몇 패킷이 손실되거나 순서가 바뀌어도 위화감이 적고
오히려 혼잡제어 메커니즘과 HandShake로 인한 지연이 사용자 경험에 더 치명적일 수 있다.
또한 DNS도 신속하게 IP주소로 바꿔주고, 연결 상태를 유지할 필요도 없기 때문에 UDP가 적절할 수 있다.
앞서 UDP를 사용하는 1번 이유에서 혼잡제어 메커니즘이 없으므로 인한 단점도 언급했다.
그렇다면 UDP를 사용할 때 네트워크가 혼잡하다면 모두 유실될텐데
데이터가 신뢰적으로 간다는 보장이 없는 UDP로 보낼 이유가 없지 않을까?
애플리케이션이 UDP를 사용할 때도 신뢰적인 데이터 전송이 가능하다.
트랜스포트 계층이 아니라 애플리케이션 계층에서 신뢰적인 전송을 위한 기능들을 제공하면 된다.
물론 이 방식은 "두 마리 토끼를 동시에 잡는 방법"으로 매우 어렵다.
하지만 이렇게 신뢰성을 애플리케이션에 포함한다면 혼잡제어로 인한 전송률 억제를 강요당하지 않고도 신뢰성 있는 통신을 할 수 있다.
책 - 컴퓨터 네트워킹 하향식 접근
컴퓨터네트워크 - 한양대학교 | KOCW 공개 강의
https://hellofuture.orange.com/en/telecoms-networks-well-equipped-to-deal-with-traffic-peaks/