El Viaje de un Paquete TCP/IP: De tu aplicación al servidor y vuelta
Tu aplicación envía un mensaje. Milisegundos después, llega a un servidor en otro continente. Pero ese “mensaje” no viaja entero: se fragmenta, se envuelve en capas, salta entre routers y atraviesa océanos. Este es el viaje de un paquete TCP/IP.
Capa 1: La Aplicación Genera Datos
Todo empieza en tu código. Digamos que haces una petición HTTP:
requests.get("https://api.ejemplo.com/users")
Tu aplicación genera datos en bruto: bytes que representan la petición HTTP. Pero estos bytes no pueden viajar solos por Internet. Necesitan ser empaquetados.
┌─────────────────────────────────────────┐
│ DATOS DE APLICACIÓN │
│ │
│ GET /users HTTP/1.1 │
│ Host: api.ejemplo.com │
│ Accept: application/json │
│ │
└─────────────────────────────────────────┘
Capa 2: TCP Segmenta y Garantiza
El protocolo TCP (Transmission Control Protocol) toma esos datos y:
- Segmenta: Divide los datos en chunks manejables
- Numera: Asigna un número de secuencia a cada segmento
- Añade puertos: Puerto origen (aleatorio) y destino (443 para HTTPS)
- Calcula checksum: Para detectar errores
┌─────────────────────────────────────────┐
│ SEGMENTO TCP │
├─────────────────────────────────────────┤
│ Puerto origen: 52431 │
│ Puerto destino: 443 │
│ Número secuencia: 1000 │
│ Número ACK: 0 │
│ Flags: SYN │
│ Checksum: 0xABCD │
├─────────────────────────────────────────┤
│ [Datos HTTP] │
└─────────────────────────────────────────┘
¿Por qué TCP? Garantiza que los datos lleguen completos y en orden. Si un paquete se pierde, lo retransmite. Perfecto para HTTP, email, transferencias de archivos.
Capa 3: IP Añade Direcciones
El protocolo IP (Internet Protocol) envuelve el segmento TCP y añade:
- IP origen: Tu dirección (ej: 192.168.1.50)
- IP destino: El servidor (ej: 203.0.113.100)
- TTL: Time To Live (cuántos saltos puede dar antes de morir)
- Protocolo: TCP = 6
┌─────────────────────────────────────────┐
│ PAQUETE IP │
├─────────────────────────────────────────┤
│ Versión: IPv4 │
│ IP origen: 192.168.1.50 │
│ IP destino: 203.0.113.100 │
│ TTL: 64 │
│ Protocolo: 6 (TCP) │
├─────────────────────────────────────────┤
│ [Segmento TCP] │
│ [Datos] │
└─────────────────────────────────────────┘
Ahora tenemos un paquete IP con dirección de origen y destino. Pero aún no puede viajar por el cable físico.
Capa 4: Ethernet lo Prepara para el Cable
Tu tarjeta de red envuelve el paquete IP en una trama Ethernet:
- MAC origen: La dirección física de tu tarjeta de red
- MAC destino: La MAC de tu router (gateway)
- EtherType: 0x0800 = IPv4
┌─────────────────────────────────────────┐
│ TRAMA ETHERNET │
├─────────────────────────────────────────┤
│ MAC destino: AA:BB:CC:DD:EE:FF (router) │
│ MAC origen: 11:22:33:44:55:66 (tu PC) │
│ EtherType: 0x0800 (IPv4) │
├─────────────────────────────────────────┤
│ [Paquete IP] │
│ [Segmento TCP] │
│ [Datos] │
├─────────────────────────────────────────┤
│ CRC: verificación de errores │
└─────────────────────────────────────────┘
¿Cómo sabe tu PC la MAC del router? Usa ARP (Address Resolution Protocol): pregunta “¿Quién tiene 192.168.1.1?” y el router responde con su MAC.
El Modelo de Encapsulación
Visualicemos la “cebolla” de capas:
┌─────────────────────────────────────────────────────────┐
│ ETHERNET │
│ ┌───────────────────────────────────────────────────┐ │
│ │ IP │ │
│ │ ┌─────────────────────────────────────────────┐ │ │
│ │ │ TCP │ │ │
│ │ │ ┌───────────────────────────────────────┐ │ │ │
│ │ │ │ DATOS HTTP │ │ │ │
│ │ │ └───────────────────────────────────────┘ │ │ │
│ │ └─────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
Aplicación → TCP → IP → Ethernet → Cable
Capa 5: El Router y NAT
Tu paquete llega al router. Aquí pasa algo importante: NAT (Network Address Translation).
Tu IP privada (192.168.1.50) no existe en Internet. El router:
- Cambia la IP origen a su IP pública (ej: 85.60.120.45)
- Cambia el puerto origen a uno único que él controla
- Guarda la asociación en una tabla NAT
Antes de NAT:
┌─────────────────────────────────┐
│ IP origen: 192.168.1.50:52431 │
│ IP destino: 203.0.113.100:443 │
└─────────────────────────────────┘
Después de NAT:
┌─────────────────────────────────┐
│ IP origen: 85.60.120.45:34567 │
│ IP destino: 203.0.113.100:443 │
└─────────────────────────────────┘
Tabla NAT del router:
┌────────────────────────────────────────────────────┐
│ 192.168.1.50:52431 ←→ 85.60.120.45:34567 │
└────────────────────────────────────────────────────┘
Cuando la respuesta regrese, el router consulta esta tabla para saber a quién entregarla.
Capa 6: El Viaje por Internet
Tu paquete ahora salta de router en router. Cada router:
- Examina la IP destino del paquete
- Consulta su tabla de rutas: “¿Hacia dónde está 203.0.113.100?”
- Reenvía por la interfaz correspondiente
- Decrementa TTL: Si llega a 0, descarta el paquete (evita loops infinitos)
- Recalcula checksums
Tu PC → Router casa → ISP local → ISP regional →
↓
Servidor ← ISP destino ← Backbone ← Punto de intercambio (IXP)
Cada salto es un “hop”. Puedes verlos con traceroute:
$ traceroute api.ejemplo.com
1 router.local (192.168.1.1) 1.234 ms
2 10.0.0.1 5.678 ms
3 core-router.isp.com 12.345 ms
4 backbone.carrier.net 45.678 ms
5 ...
12 api.ejemplo.com (203.0.113.100) 78.901 ms
Capa 7: El Servidor Recibe
El paquete llega al servidor destino. Ahora se desencapsula en orden inverso:
Cable → Ethernet → IP → TCP → Datos HTTP
1. Tarjeta de red recibe trama Ethernet
→ Verifica CRC, extrae paquete IP
2. Stack IP del kernel
→ Verifica que la IP destino es suya
→ Extrae segmento TCP
3. Stack TCP del kernel
→ Verifica puerto destino (443)
→ Reensambla si hay múltiples segmentos
→ Entrega datos al proceso escuchando
4. Aplicación (Nginx, Node, etc.)
→ Recibe la petición HTTP completa
Capa 8: La Respuesta
El servidor genera una respuesta y hace el proceso inverso:
SERVIDOR TU PC
│ │
Aplicación genera JSON │ │
│ │ │
▼ │ │
TCP segmenta │ │
│ │ │
▼ │ │
IP empaqueta │ │
src: 203.0.113.100 │ │
dst: 85.60.120.45 │ ─── Internet ─── │
│ │ │
▼ │ │
Ethernet │ │
│ │ │
└───────────────┼────────────────────────────────┤
│ │
│ Router NAT │
│ traduce dst │
│ a 192.168.1.50
│ │ │
│ ▼ │
│ Tu PC recibe │
│ desencapsula │
│ App obtiene │
│ el JSON │
El Diagrama Completo
┌─────────────────────────────────────────────────────────────────────┐
│ TU COMPUTADORA │
│ │
│ Aplicación │
│ │ datos │
│ ▼ │
│ TCP (puerto 52431 → 443, seq, ack, checksum) │
│ │ │
│ ▼ │
│ IP (192.168.1.50 → 203.0.113.100, TTL=64) │
│ │ │
│ ▼ │
│ Ethernet (tu MAC → MAC del router) │
│ │ │
└───────┼─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ ROUTER (NAT) │
│ │
│ Recibe trama → Extrae IP → Aplica NAT │
│ 192.168.1.50:52431 → 85.60.120.45:34567 │
│ Nueva trama Ethernet → Envía al ISP │
│ │
└───────┼─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ INTERNET │
│ │
│ Router ISP → Router regional → Backbone → IXP → ... │
│ │
│ Cada router: │
│ 1. Lee IP destino │
│ 2. Consulta tabla de rutas │
│ 3. Decrementa TTL │
│ 4. Reenvía │
│ │
└───────┼─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ SERVIDOR │
│ │
│ Ethernet → IP → TCP → Aplicación │
│ │ │
│ ▼ │
│ Procesa petición │
│ │ │
│ ▼ │
│ Genera respuesta │
│ │ │
│ (proceso inverso) │
│ │
└─────────────────────────────────────────────────────────────────────┘
¿Cuánto tiempo toma cada paso?
| Paso | Tiempo típico |
|---|---|
| Encapsulación local | < 1ms |
| Router local + NAT | 1-5ms |
| Cada hop en Internet | 1-20ms |
| Total ida (10-15 hops) | 20-100ms |
| Procesamiento servidor | 5-500ms |
| Total ida y vuelta | 50-200ms |
El RTT (Round-Trip Time) es lo que mides con
ping. Un servidor en tu país: ~20-50ms. Otro continente: ~100-300ms.
¿Qué puede fallar?
| Problema | Síntoma | Causa |
|---|---|---|
| TTL exceeded | Paquete muere | Loop de routing o destino muy lejano |
| Connection refused | RST inmediato | Puerto cerrado en destino |
| Timeout | Sin respuesta | Firewall, servidor caído, ruta rota |
| Packet loss | Retransmisiones TCP | Congestión, enlace saturado |
| Fragmentación | Lentitud | MTU mismatch, paquetes muy grandes |
Herramientas para inspeccionar
# Ver tu IP y rutas
ip addr
ip route
# Ver conexiones activas
ss -tuln
netstat -an
# Seguir el camino de un paquete
traceroute api.ejemplo.com
mtr api.ejemplo.com
# Capturar paquetes en tiempo real
sudo tcpdump -i eth0 host api.ejemplo.com
sudo wireshark
Conclusión
Un simple paquete TCP/IP:
- Nace como datos en tu aplicación
- Se envuelve en TCP (puertos, secuencia, garantía de entrega)
- Se envuelve en IP (direcciones origen/destino)
- Se envuelve en Ethernet (MACs para el cable físico)
- Cruza NAT en tu router (IP privada → pública)
- Salta entre 10-20 routers por Internet
- Llega al servidor y se desenvuelve capa por capa
- Regresa siguiendo el proceso inverso
Todo esto ocurre miles de veces por segundo mientras navegas. Cada paquete es un pequeño viajero con su pasaporte (headers) cruzando fronteras (routers) hasta llegar a destino.
Este post es parte de la serie “El Viaje de la Información”, donde exploramos qué sucede realmente cuando interactuamos con nuestros sistemas.