Guía
TCP vs UDP, explicado desde los puertos de tu propia máquina
14 de septiembre de 20264 min de lectura
Casi todas las explicaciones de TCP y UDP parten por el modelo OSI y te pierden al tercer párrafo. Esta parte por algo que puedes comprobar en tu Mac en diez segundos.
Son dos conjuntos separados de puertos
TCP tiene 65.536 puertos. UDP tiene sus propios 65.536 puertos. No los comparten y no chocan entre sí.
Lo puedes demostrar. Ata un socket TCP al puerto 9955 y déjalo escuchando, y después ata un socket UDP al 9955 al mismo tiempo. Los dos funcionan. El sistema operativo los trata como direcciones completamente distintas, porque el protocolo es parte de la dirección.
Esto importa en la práctica cuando una herramienta te dice que un puerto está ocupado y otra te dice que está libre. Probablemente no están mirando el mismo protocolo. Es lo primero que hay que revisar antes de asumir que una herramienta te está mintiendo.
Qué te da TCP realmente
TCP es una conversación con principio, medio y final.
Antes de que se mueva un solo dato, los dos lados hacen un saludo para confirmar que ambos están ahí y listos. Después de eso, TCP garantiza tres cosas: tus bytes llegan, llegan en el orden en que los mandaste, y llegan exactamente una vez. Si un paquete se pierde, TCP se da cuenta y lo manda de nuevo. Si llegan desordenados, TCP los ordena antes de que tu programa los vea.
Todo eso tiene un costo. El saludo agrega una ida y vuelta antes del primer byte. La garantía de orden significa que un solo paquete perdido detiene todo lo que viene atrás hasta que llegue la retransmisión.
Para casi todo lo que construyes, ese intercambio vale la pena de forma obvia. HTTP, SSH, conexiones a bases de datos, tu servidor de desarrollo, todo TCP.
Qué te da UDP en cambio
UDP manda un paquete y deja de preocuparse. Sin saludo, sin confirmación, sin retransmisión, sin orden. Si llega, llegó. Si no, nadie te avisa.
Suena inútil hasta que piensas en una videollamada. Un paquete de audio de hace 400 milisegundos no vale nada, y detener la llamada para esperarlo es peor que saltárselo. Prefieres un pequeño corte ahora antes que audio perfecto que llega tarde. Lo mismo para video en vivo, juegos en línea y casi todo el streaming.
DNS es el otro caso clásico. Una consulta es una pregunta chica y una respuesta chica. Armar una conexión TCP para eso es más trabajo que la consulta misma, así que DNS usa UDP por defecto y recurre a TCP cuando la respuesta es muy grande.
Por qué casi todo lo que depuras localmente es TCP
Cuando andas cazando un conflicto de puertos, casi siempre es TCP, porque lo que entra en conflicto son servidores, y los servidores casi siempre son TCP.
Por eso el comando estándar lleva un filtro de TCP:
lsof -i -P -n -sTCP:LISTEN
-sTCP:LISTEN deja solo los sockets TCP en estado LISTEN. Saca las conexiones ya establecidas y todo lo que sea UDP, que es lo que hace que la salida sea legible.
Si sí quieres ver UDP:
lsof -i udp
Vas a notar algo. Los sockets UDP no tienen estado LISTEN, y eso no es una rareza de la herramienta. LISTEN es un concepto de TCP, parte de su máquina de estados de conexión. UDP no tiene conexiones, así que no hay estado en el cual estar. Un socket UDP está atado a un puerto o no lo está.
Una regla práctica para leer tu propia máquina
Si andas persiguiendo un “port already in use”, asume TCP y usa el comando con filtro. Si un puerto se ve genuinamente libre en TCP pero algo insiste en que está tomado, revisa UDP antes de concluir que algo está roto.
Y recuerda que el protocolo es parte de la identidad de un puerto. “Puerto 5353” no es una descripción completa. En un Mac, el UDP 5353 es mDNS, lo que hace funcionar los nombres .local, y está ocupado en prácticamente toda máquina.
Relacionado
También escribimos sobre qué es un puerto en concreto y cómo están divididos los rangos, que completan el resto de este panorama.
Bosun lista lo que está escuchando en tu Mac desde la barra de menú, con el proceso, contenedor o túnel detrás de cada puerto. macOS 14 o posterior, prueba de 14 días, sin cuenta.
Ve esto en vez de escribirlo
Bosun vive en tu barra de menú y muestra cada puerto abierto en tu Mac, en vivo, mapeado al proceso detrás. Un clic para matarlo, SIGTERM primero. Útil la primera vez que pasa esto. Realmente útil la quinta vez que pasa en una misma tarde.