19 puntos por GN⁺ 2025-11-16 | 1 comentarios | Compartir por WhatsApp
  • TCP (Transmission Control Protocol) es el protocolo esencial de Internet que permite una transmisión de datos confiable y en orden incluso en entornos de red inestables
  • Mientras que IP solo se encarga de entregar datos entre hosts, TCP realiza comunicación entre procesos basada en puertos y se ocupa de la recuperación de errores, retransmisión y control de orden
  • Mediante flow control y congestion control, ajusta la transmisión para no exceder los límites del búfer de recepción o del ancho de banda de la red
  • A través de ejemplos de un servidor TCP simple y un servidor HTTP implementados en C, se explica en detalle el proceso de creación de sockets, bind, listen, aceptación de conexiones, envío y recepción
  • La estructura interna de TCP, como los números de secuencia y ACK, ventana, checksum y flags (SYN/ACK/FIN/RST), es la base clave que hace posible el funcionamiento estable del Internet actual

La necesidad y el papel de TCP

  • IP solo se encarga de entregar paquetes entre hosts, y para la comunicación entre procesos se necesita una capa de transporte como TCP o UDP
    • La dirección IP se compara con un “edificio” y el puerto con un “apartamento”, donde cada aplicación se comunica al enlazarse a un puerto
  • TCP oculta la inestabilidad de la red, como la pérdida, duplicación o desorden de paquetes, y garantiza confiabilidad mediante retransmisión y checksum
  • Los routers se mantienen simples, y la confiabilidad se maneja en ambos extremos de la comunicación, lo que reduce la complejidad de la infraestructura de red
  • Gracias a esta estructura, servicios clave de Internet como HTTP, SMTP y SSH pueden funcionar de forma estable

Flow control y congestion control

  • El receptor almacena temporalmente los datos mediante el receive buffer del kernel, cuyo tamaño se configura con net.ipv4.tcp_rmem
  • El emisor regula cuánto enviar a partir de la cantidad de datos que el receptor puede aceptar, indicada en el campo window
  • Para evitar la congestión causada por diferencias de ancho de banda en toda la red, TCP incorpora algoritmos de congestion control
    • A raíz del incidente de congestion collapse ocurrido en 1986, se añadió el mecanismo de back-off

Ejemplos de servidor TCP y servidor HTTP

  • Un servidor echo TCP básico escrito en C recibe la entrada del cliente y la devuelve agregando “you sent:”
    • Usa la API de sockets de Berkeley como socket(), bind(), listen(), accept(), send() y recv()
    • Cuando el servidor está en sleep(), los datos del cliente esperan en el receive buffer y luego se procesan secuencialmente
  • En un ejemplo simple de servidor HTTP/1.1, se aceptan solicitudes a través de una conexión TCP y se envían el encabezado HTTP/1.1 200 OK y el cuerpo
    • Cuenta las solicitudes con i, y al hacer curl localhost:8080 muestra una respuesta con la forma “[1] Yo, I am a legit web server”

Estructura del segmento TCP y campos clave

  • Un segmento TCP está compuesto por puerto de origen y destino, número de secuencia, número ACK, tamaño de ventana, checksum y flags
    • A cada puerto se le asignan 16 bits, por lo que se pueden usar hasta 64K puertos
    • Una conexión se identifica mediante la 5-tupla (protocolo, IP de origen, puerto de origen, IP de destino, puerto de destino)
  • El número de secuencia indica el rango de bytes transmitidos, y el número ACK indica los bytes recibidos correctamente
    • Si faltan datos, el ACK se detiene en ese punto, y tras la retransmisión se actualiza como ACK acumulativo
  • Los bits de flags controlan el estado de la conexión
    • SYN/ACK establecen la conexión mediante el 3-way handshake
    • FIN cierra la conexión mediante el 4-way handshake
    • RST libera la conexión de inmediato ante un cierre anormal o un error
  • El campo window indica la cantidad de datos que se pueden recibir, y con el comando ss se puede revisar el estado del búfer (rb131072, tb16384)
  • El checksum detecta errores sumando unidades de 16 bits dentro del segmento

Conclusión

  • TCP garantiza confiabilidad, orden e integridad, y permite que las aplicaciones funcionen correctamente incluso en entornos de Internet inestables
  • Hace décadas era difícil incluso transferir unos pocos KB, pero hoy el streaming 4K es algo cotidiano
  • La sofisticación del diseño y la implementación de TCP que hizo posible esta comunicación estable es la base del crecimiento continuo de Internet

1 comentarios

 
GN⁺ 2025-11-16
Comentarios en Hacker News
  • Si intentas construir un flujo de datos confiable sobre una capa de datagramas no confiable, al final obtienes algo casi idéntico a TCP
    Las limitaciones iniciales de TCP eran un tamaño de ventana pequeño, manejo deficiente de paquetes perdidos y el hecho de que solo administraba un único flujo
    Para resolver estos problemas aparecieron SCTP y QUIC
    Los algoritmos de control de congestión no son parte del protocolo, sino código que se ejecuta en ambos extremos de cada conexión
    Los algoritmos iniciales (Reno, Vegas, etc.) eran simples pero suficientemente efectivos, y desde entonces ha continuado la investigación para abordar búferes grandes, RTT largos, equidad y otros temas

    • También creo que los desarrolladores web tienen parte de la culpa por no haber aprovechado bien los flujos múltiples
      Hace tiempo hice una librería en JavaScript que permitía controlar prioridades y cancelación de varias descargas dentro de un solo flujo
      Con un script de GreaseMonkey hacía que las miniaturas de un sitio de citas se precargaran en segundo plano y según la posición del scroll
      Como resultado, reduje la carga del servidor mientras mejoraba la experiencia del usuario
      Curiosamente, le compartí ese script a una pareja potencial y hasta hoy seguimos juntos — en cierto modo era un Tinder antes de Tinder
    • Cuando se creó TCP, predominaba una forma de pensar basada en la conmutación de circuitos (circuit switching) de las redes telefónicas
      TCP tiene una estructura que ofrece un circuito virtual sobre una red de conmutación de paquetes, y la idea de implementar confiabilidad mediante retransmisión provino de la red francesa Cylades
    • Uno de los defectos fundamentales de TCP es su imposibilidad de asegurarse
      Un atacante puede inyectar datos en cualquier punto de la red o cortar la conexión con un paquete RST
      Bloquear RST con un firewall mejora la estabilidad, pero los ataques de desincronización mediante números de secuencia falsificados siguen siendo posibles
      Por eso, todas las aplicaciones tienen que implementar una función de reanudación en una conexión aparte, y además cargar con el problema del slow start de TCP
      También me parece ineficiente el propio concepto de separar direcciones y puertos
    • Algunas aplicaciones funcionan perfectamente bien con una sola conexión TCP
      Por ejemplo, en DNS over TLS (DoT) se pueden enviar varias consultas al mismo tiempo por una sola conexión TCP y recibir las respuestas sin importar el orden
      Es más eficiente y más cortés que abrir varias conexiones
      No sé si QUIC será más rápido, pero el soporte del servidor todavía es limitado
      HTTP/1.1 pipelining hace algo parecido, pero las respuestas llegan en secuencia
    • El hecho de que los algoritmos de control de congestión de TCP estén fuera del protocolo fue algo muy innovador para su época
      Pero muchas clases universitarias no enfatizan este punto, así que mucha gente termina creyendo erróneamente que TCP tiene un solo algoritmo
  • Quisiera preguntar si alguien le tiene cariño a SCTP
    SCTP es un protocolo que combina la orientación a mensajes de UDP con la confiabilidad de TCP, y soporta multistreaming y multihoming
    Puede transmitir varios flujos independientes en paralelo, así que permite enviar al mismo tiempo el texto y las imágenes de una página web
    Para más detalles, ver Wikipedia: Stream Control Transmission Protocol

    • SCTP solo resuelve la mitad del problema e introduce varios defectos nuevos
      Al final, la mejor respuesta es una capa de confiabilidad sobre UDP, es decir, QUIC
    • Como alguien que disfruta usar BSD y trabaja con Erlang, adoro SCTP
  • Me preguntaba si se podían enviar paquetes directamente usando solo IP
    Parecía que los routers intermedios rechazarían paquetes que no fueran TCP o UDP

    • Se puede manipular y enviar paquetes IP directamente
      En IPv4 basta con especificar uno de los valores de 0 a 255 de la lista de números de protocolo de IANA
      Los routers troncales no inspeccionan ese campo, aunque los equipos NAT o del ISP sí podrían hacerlo
      Entre dos servidores Linux se puede incluso comunicar usando números experimentales (253, 254)
    • Tampoco hay que olvidar ICMP. En IPv6 es aún más importante
      Protocolos como IPsec, GRE y L2TP tampoco son TCP/UDP
      En redes corporativas con firewall o entornos con NAT, un protocolo arbitrario puede ser bloqueado
      NAT rompió el principio end-to-end, y al final la gente empezó a montar todo sobre TCP o UDP, o incluso sobre HTTP
    • Si no hay NAT ni balanceador de carga, no hay problema, pero como hoy son comunes, IPv6 podría ser mejor
    • Un router es un dispositivo de capa 3, así que no le importa si es TCP/UDP o no
      A lo mucho, el impacto sería una menor entropía en el hash de ECMP
      Al final, la clave es si la otra parte entiende ese protocolo
    • TCP y UDP no son más que payload de IP, y los routers no los interpretan
      Los números de puerto son solo identificadores de servicio dentro del nodo
  • RUDP (Plan9) era un excelente punto medio entre TCP y UDP
    Ver Reliable User Datagram Protocol

  • Como TCP se volvió el valor predeterminado, terminó usándose incluso cuando no hacía falta confiabilidad ni garantía de orden
    Ahora, con la expansión de HTTP/3 (basado en QUIC), la situación podría mejorar
    Sin embargo, QUIC es mucho más complejo, y su potencia solo le resulta útil a algunos
    Una capa de cifrado simple al estilo UDP + WireGuard podría ser una mejor alternativa

  • TCP es uno de los grandes inventos de la humanidad, pero no anticipó el dominio de las redes semi-conectadas (basadas en NAT)

    • Surge la pregunta: “¿Te refieres a NAT?”
    • Si uno volviera a 1981 y propusiera “usar un rango limitado de direcciones en vez de direcciones globales, y hacer que algunos nodos sean inaccesibles”,
      los ingenieros de esa época probablemente preguntarían por qué complicarlo tanto a propósito
      Al final, la actual estructura de enlaces asimétricos y la distinción cliente-servidor surgieron de esa forma de pensar
  • Los algoritmos de control de congestión de TCP tienen efectos interesantes que muchos desarrolladores desconocen
    Si envías datos en una conexión nueva, la transmisión inicial es lenta, y el aumento de velocidad está determinado por la latencia
    En los centros de datos, reducir el RTT apenas unos microsegundos puede mejorar mucho la velocidad
    La mayoría de los stacks TCP calculan el aumento de velocidad por segmentos y no por bytes, así que con jumbo frames la subida puede ser 6 veces más rápida
    AWS dedica mucho esfuerzo al bajo switching latency y al soporte para jumbo frames por esta razón
    Los expertos ajustan este tipo de cosas, pero la mayoría solo se pregunta por qué no obtiene 10 Gbps en un enlace de 10 Gbps

  • Crear tu propio protocolo sobre IP era muy sencillo
    Hasta hace 15 años, se podía experimentar en Python armando paquetes a mano