7. UDP (User Datagram Protocol)

El User Datagram Protocol fue definido en la RFC 768 como una alternativa ligera a TCP. No establece sesiones, no confirma recepciones y deja en manos de la aplicación cualquier mecanismo de recuperación. A cambio, ofrece latencia mínima y sobrecarga casi nula.

UDP brilla cuando una pequeña pérdida es preferible a un retraso importante: streaming multimedia, juegos en línea, VoIP y protocolos como DNS dependen de su simplicidad para mantenerse rápidos.

7.1 Características generales

  • Sin conexión: cada datagrama es independiente. No existe handshake ni estados intermedios.
  • Sin garantía de entrega: no retransmite paquetes perdidos ni ordena el flujo. La aplicación decide qué hacer con los datos faltantes.
  • Baja sobrecarga: el encabezado tiene solo 8 bytes, lo que reduce el consumo de ancho de banda y CPU.
  • Broadcast y multicast: puede enviar un datagrama a varios receptores a la vez aprovechando direcciones especiales de capa de red.

Estas propiedades convierten a UDP en un transporte ideal para mensajes cortos como consultas DNS o para flujos continuos donde la temporización es crítica.

7.2 Encabezado UDP

El encabezado siempre ocupa 8 bytes y contiene cuatro campos de 16 bits:

Campo Función
Puerto origen Identifica el servicio o la aplicación que envía el datagrama (puede ser cero si no se necesita respuesta).
Puerto destino Proceso receptor dentro del host remoto.
Longitud Tamaño total del datagrama (encabezado + datos).
Checksum Verifica la integridad del datagrama y de una pseudo-cabecera IP. En IPv4 es opcional, en IPv6 es obligatorio.

La ausencia de números de secuencia y ACK simplifica al protocolo, pero implica que la aplicación debe manejar pérdidas o duplicados si le resultan problemáticos.

7.3 Ventajas frente a TCP

  • Latencia reducida: al no esperar confirmaciones, el receptor procesa los datos apenas llegan.
  • Menor sobrecarga: ideal para redes IoT y dispositivos con recursos limitados.
  • Soporte natural para multicast/broadcast.
  • Permite diseñar protocolos personalizados con control total sobre los tiempos.

7.4 Desventajas y responsabilidades de la aplicación

El lado negativo es evidente: UDP no ofrece confiabilidad. Si la aplicación necesita orden, detección de pérdidas o control de flujo, debe implementarlo por su cuenta (por ejemplo, QUIC o RTP incluyen sus propios mecanismos).

Tampoco existe control de congestión integrado, por lo que un flujo UDP puede inundar la red si el desarrollador no regula el ritmo. Servicios bien diseñados miden latencias y aplican lógicas de backoff para convivir con otros tráficos.

7.5 Casos de uso

Aplicación Motivo para usar UDP
DNS Consultas breves donde es preferible reenviar antes que mantener una sesión.
VoIP y videollamadas La continuidad del audio o video es más importante que la perfección de cada paquete.
Streaming en vivo Protocolos como RTP priorizan la latencia para mantener sincronizados audio y video.
Juegos en línea Las actualizaciones de posición pierden relevancia rápidamente; es mejor enviar la información más reciente.
Servicios de descubrimiento El soporte para broadcast/multicast permite anunciar dispositivos en una red local.

7.6 Comparación con TCP

Aunque la comparación completa aparece en el tema 8, conviene adelantar cómo difieren ambos protocolos:

  • TCP requiere tres mensajes para abrir una sesión; UDP envía datos inmediatamente.
  • TCP usa control de flujo y congestión; UDP depende de la aplicación.
  • TCP garantiza orden y entrega, lo que aumenta la latencia; UDP entrega lo disponible de inmediato.

7.7 Ejemplo en Python: eco UDP

Con pocas líneas es posible crear un cliente y un servidor de eco para observar la ausencia de conexiones persistentes:

Cliente/servidor UDP

import socket

def servidor_udp(puerto=9999):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("0.0.0.0", puerto))
    print("Servidor UDP listo")
    while True:
        datos, direccion = sock.recvfrom(1024)
        print("Recibido", datos, "de", direccion)
        sock.sendto(datos.upper(), direccion)

def cliente_udp(mensaje, host="127.0.0.1", puerto=9999):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(mensaje.encode(), (host, puerto))
    respuesta, _ = sock.recvfrom(1024)
    print("Respuesta:", respuesta.decode())

# Ejecutar servidor_udp() en una terminal y cliente_udp("hola UDP") en otra

Obsérvese que el servidor no necesita aceptar conexiones: simplemente procesa cada datagrama que llega y responde usando la dirección informada en la llamada recvfrom.

flujo de datagramas UDP entre cliente y servidor

7.8 Diagnóstico rápido con PowerShell

Aunque la mayoría de las herramientas se centran en TCP, Windows ofrece códigos para probar puertos UDP específicos:

Comandos útiles

Test-NetConnection -ComputerName 1.1.1.1 -Port 53 -InformationLevel Detailed -Udp

Get-NetUDPEndpoint | Select-Object -First 5 -Property LocalPort, RemoteAddress, OwningProcess

El primer comando envía un datagrama al puerto 53 (DNS) y reporta si llegó respuesta. El segundo lista los sockets UDP abiertos, lo que ayuda a identificar servicios que escuchan en la máquina local.

7.9 Consideraciones de seguridad

UDP es susceptible a ataques de spoofing porque no verifica el origen. Muchas amenazas de amplificación DDoS explotan servicios UDP mal configurados (por ejemplo, servidores DNS abiertos).

  • Restringir el acceso a puertos UDP expuestos a Internet.
  • Implementar listas blancas o autenticación a nivel de aplicación.
  • Monitorear tasas de envío para detectar patrones que indiquen abusos.

7.10 Cierre

UDP ilustra el compromiso entre simplicidad y confiabilidad: elimina casi todo el mecanismo de supervisión para priorizar la velocidad. Cuando una aplicación puede tolerar pérdidas o dispone de su propia capa de corrección, UDP se vuelve imbatible.

En el próximo tema se compararán formalmente TCP y UDP para elegir la opción adecuada en cada escenario.