UDP에대해 공부하자! UDP는 트랜스포트 계층 프로토콜이 할 수 있는 최소 기능으로 동작한다. UDP는 다중화/역다중화 + 간단한 오류 검사 기능을 제외하면 IP에 아무것도 추가하지 않는다. 사실 애플리케이션 개발자가 UDP를 선택한다면 애플리케이션은 거의 IP와 직접 통신하는 셈이다. UDP는 프로세스로부터 메시지 가져와서 다중화/역다중화 서비스에 대한 출발지 포트 번호 필드와 목적지 포트 번호 필드를 첨부하고 다른 두 필드를 추가 후 최종 세그먼트를 네트워크 계층으로 넘긴다. 네트워크 계층은 세그먼트를 IP 데이터그램으로 캡슐화하고, 세그먼트를 수신 호스트에 전달하기 위해 최선을 다한다. 만약 세그먼트가 수신 호스트에 도착한다면, UDP는 세그먼트의 데이터를 프로세스로 전달하기 위해 목적지 포트 번호를 이용한다.
DNS는 전형적으로 UDP를 사용하는 애플리케이션 계층 프로토콜의 예. 목적지 종단 시스템상에서 동작하는 UDP 개체와 호스트 측 UDP는 어떠한 핸드셰이크도 수행하지 않고 메시지에 헤더 필드를 추가한 후에 최종 세그먼트를 네트워크 계층으로 넘긴다. 네트워크 계층은 UDP 세그먼트를 데이터그램으로 캡슐화하고 네임 서버에 데이터그램을 넘겨준다. 이때 질의 호스트에서의 DNS 애플리케이션은 질의대한 응답을 대기하고 기다려도 수신 못하면 다른곳에 다시 질의하거나 응답을 수신 할 수 없을을 요구자한테 통보한다.
UDP가 더 적합한 경우
- 부슨 데이터를 언제 보낼지에 대해서 애플리케이션 레벨에서 더 정교한 제어: UDP는 프로세스가 데이터를 UPD로 보내자 마자 세그먼트로만들고 네트워크 계층으로 전달한다. 반면에, TCP는 혼잡제어 메커니즘을 가지고 있다. 이 메커니즘은 목적지 호스트들과 출발지 호스트들 사이에서 하나 이상의 링크가 과도히 복잡해지면, 트랜스포트 계층 TCP 송신자를 제한한다. 또한 TCP는 신뢰적인 전달이 얼마나 오래걸리든 세그먼트 수신 여부를 확인 응답할 때까지 세그먼트 재전송을 계속 할 것임. 실시간 앱음 최소 전송률을 요구할 때도 있고, 지나치게 지연되는 세그먼트 전송을 원치 않으며, 조금의 데이터 손실은 허용할 수도 있으므르로, TCP의 서비스 모델은 이런 앱의 요구사항과는 맞지 않는다.
- 연결 설정이 없음: UDP는 핸드셰이크가 없다. 그러므로 연결을 위한 어떤 지연도 없다. 이게 DNS가 UDP 위해서 동작하는지에 대한 일반적인 이유. HTTP에서 TCP 연결 설정 지연은 웹 문서 다운로드 지연의 심각한 원인이다. 실제 구글 크롬에서 사용되는 QUIC(quick UDP internet connection) 프로토콜은 기본 트랜스포트 프로토콜로 UDP를 쓰고 UDP위에 앱 계층 프로토콜의 안정성을 구현한다.
- 연결 상태 없음: TCP는 종단 시스템에서 연결 상태를 유지한다. 이 연결 상태는 수신 버퍼, 송신 버퍼, 혼잡 제어 파라미터, 순서 번호, 확인 응답 번호 파라미터를 포함한다. 반면에, UDP는 연결 상태 유지 않으며 이 파라미터중 어떤 것도 기록하지 않는다. 이런 특징으로 UDP에서 동작하는 애플리케이션이 좀 더 많은 액티브 클라이언트를 수용할 수 있다.
- 작은 패킷 헤더 오버헤더: TCP는 세그먼트마다 20바이트의 헤더 오버헤드 가지지만, UDP는 단지 8바이트의 오버헤드를 가진다.

2장에서 초기 버전의 HTTP는 TCP 통해 실행되었지만 최신 버전의 HTTP는 UDP를 통해 실행되어 앱 계층에서 자체 오류 제어 및 혼잡 제어를 제공한다고했다.
오늘날 멀티미디어 앱을 UDP위에서 동작시키는 방법이 일반적으로 사용되지만 아직 논란의 여지가 있다. UDP는 혼잡 제어를 하지 않는다. 그러나 혼잡 제어는 네트워크가 꼭 필요한 작업을 할 수 없게 되는 폭주 상태에 빠지는것을 막기위해 반드시 필요하다. 만약 모두가 혼잡 제어를 안하고 높은 비트의 비디오 스트리밍을 한다면, 라우터에 많은 패킷 오버플로가 생길거고, 이는 소수의 UDP 패킷만이 목적지에 가게 될 것이다. 또한 제어되지 않는 UDP 송산자에 의해 발생한 높은 손실률은 그 손실률을 감소 시키기위해 TCP 송신자들이 속도를 줄이게 할 것이다. 그러므로 UDP의 혼잡 제어 결여는 UDP 송수신자간 높은 손실률 초래할 수 있고, TCP 세션의 혼잡이 발생할 수 있으며 이는 잠재적으로 심각한 문제점이다.
UDP 사용시에도 신뢰적인 데이터 전송이 가능하다. 만약 앱이 신뢰성을 앱 자체에서 제공한다면 신뢰적인 데이터 전송이 가능하다(다음 절에서 알아볼 확인응답 메커니즘과 재전송 메커니즘 추가 등). 앞에서 QUIC 프로토콜은 UDP상에서 앱 계층에 신뢰성을 구현했다고 했다. 그러나 이건 앱 개발자들이 오랜 시간 분주하기 디버깅을 하는 어려운 작업. 하지만 이렇게하면 두 마리 토끼를 잡는 격이다. 즉, 앱 프로세스들은 TCP의 혼잡 제어 메커니즘에 의해 전송률 억제를 강요당하지 않고도 신뢰적으로 통신할 수 있다.
3.3.1 UDP 세그먼트 구조
UDP 세그먼트 구조는 RFC 768에 정의되있다. 애플리케이션 데이터는 UDP 데이터그램의 데이터 필터에 위치한다. 예를 들어, DNS에 대한 데이터 필드에는 질의 메시지나 응답 메시지가 포함된다. UDP 헤더는 2바이트씩 구성된 단 4개의 필드만 가진다. 앞 절에서 설명한것처럼, 포트 번호는 목적지 호스트가 목적지 종단 시스템에서 동작하는(역다중화 기능 수행) 정확한 프로세스에게 데이터 넘기게 해준다.
체크섬은 세그먼트에 오류가 발생했는지 검사위해 수신 호스트가 사용한다. 사실 체크섬은 UDP 세그먼트 이외에 IP 헤더의 일부 필드도 계산하지만, 전체 그림을 보기위해 이런 세부 사항은 무시한다 일단.
길이 필드는 헤더를 포함하는 UDP 세그먼트의 길이(바이트 단위)를 나태낸다.
3.3.2 UDP 체크섬
UDP 체크섬은 오류 검출을 위한 것. 수신지에서 UDP 세그먼트 안의 비트에 대한 변경사항이 있는지 검사하는 것이다.
송신자 측에서 UDP는 세그먼트 안에 모든 16비트 워드의 합산에 대해 다시 1의 보수를 수행하며, 합산 과정에서 발생하는 오버플로는 윤회식 자리올림을 한다. 이 결과값이 UDP의 체크섬 필드에 삽입된다.
체크섬의 간단한 예를 알아보자. RFC 1071 참고. 예를 들어 다음과 같은 3개의 16비트 워드가 있다고 하자.
0110011001100000
0101010101010101
1000111100001100
이런 16비트 워드에서 처음 2개의 워드 합은 다음과 같다.
0110011001100000
0101010101010101
----------------
1011101110110101
앞 계산의 합에 세 번째 워드를 더하면 다음과 같은 결과가 나온다.
1011101110110101
1000111100001100
----------------
0100101011000010
마지막합은 오버플로가 있고 이를 윤회식 자리올림을 했음을 유의하자. 1의 보수는 모든 0을 1로 변환하고 모든 1을 0으로 변환하면 구할 수 있다. 그러니 0100101011000010의 1의 보수는 1011010100111101 이고 이것이 체크섬이 된다. 수신자에서는 체크섬을 포함한 4개의 모든 16비트 워드들이 더해진다. 만약 패킷에 어떤 오류도 없다면, 수신자에서의 합은 1111111111111111이 될것이다! 만약 하나라도 0이 면 패킷에 오류가있었음을 알 수 있다.
많은 링크 계층 프로토콜(인기있는 이더넷 프로토콜 포함)이 오류검사를 제공하는데, 왜 UDP가 체크섬을 제공할까? 그 이유는 출발지와 목적지 사이의 모든 링크가 오류 검사를 제공한다는 보장이 없게 때문이다. 링크에 잘 전달되어도 라우터의 메모리에 저장될때 비트오류 발생할 수도 있다. 주어진 링크 간의 신뢰성과 메모리 오류 검사가 보장 안되고, 종단 간의 데이터 전송 서비스가 오류 검사를 제공해야 한다면 UDP는 종단 기반으로 트랜스포트 계층에서 오류 검사를 제공해야만 한다.
이것이 시스템 설계에서 그 유명한 종단과 종단의 원칙(end-end principle)의 한 예. 즉, 어떤 기능(이 경우 오류 검사)이 종단 기반으로 구현되어야 하므로, ‘하위 레벨에 있는 기능들은 상위 레벨에서 이들을 제공하는 비용과 비교했을 때 중복되거나 거의 가치가 없을 수 있다’는 것이다.
IP는 어떠한 2계층 프로토콜에서도 동작해야 하므로, 트랜스포트 계층은 안전장치로 오류 검사를 제공하는 것이 유용하다. UDP는 오류 검사를 제공하지만, 오류를 회복하기 위한 어떤 일도 하지 않는다. 일부 UDP 구현에선 손상된 건 그냥 버리기도하고, 어떤건 경고와 함께 손상된 세그먼트를 앱에 주기도 한다.