- .1. La Abstracción de Sockets y la Capa de Transporte
- Definición de Socket: Un Socket (o punto final de comunicación / endpoint) es una abstracción de software del sistema operativo que actúa como una interfaz de Entrada/Salida (E/S) a través de la cual los procesos pueden enviar y recibir datos en una red de computadoras
- .
- Identificación del Endpoint: Un socket se identifica unívocamente en la red mediante una tupla de 5 elementos (conocida como 5-tuple)
- :
- Puertos: Los sockets utilizan puertos para direccionar los procesos . Los puertos bien conocidos (Well-known Ports) van del 0 al 1023 (por ejemplo, HTTP en el puerto 80, HTTPS en el 443 o SSH en el 22)
- .
┌──────────────────────────────────────────┐
│ SOCKETS EN LA CAPA DE TRANSPORTE │
└────────────────────┬─────────────────────┘
│
┌─────────────────────────────┴─────────────────────────────┐
▼ ▼
┌───────────────────────────┐ ┌───────────────────────────┐
│ SOCKETS TCP │ │ SOCKETS UDP │
│ (Stream-Oriented) │ │ (Datagram-Oriented) │
├───────────────────────────┤ ├───────────────────────────┤
│ • Orientado a Conexión │ │ • Sin Conexión (Connectionless)
│ • Flujo de Bytes Continuo │ │ • Conserva Límites (Datagrama)
│ • Control de Flujo/Congestión │ • Sin Garantía de Entrega │
│ • Fiabilidad (ACKs/Retrans) │ • Mínima Sobrecarga (Low Latency)
└───────────────────────────┘ └───────────────────────────┘
- Orientación a conexión: Antes de transmitir datos, los sockets cliente y servidor deben ejecutar una negociación de 3 vías (Three-way Handshake: SYN, SYN-ACK, ACK) para establecer la conexión
- .
- Sin Conexión (Connectionless): No requiere negociación ni establecimiento de enlace previo
- .
PROCESO SERVIDOR PROCESO CLIENTE
┌──────────────────────┐ ┌──────────────────────┐
│ socket() (Crear) │ │ socket() (Crear) │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
┌──────────▼───────────┐ ┌──────────▼───────────┐
│ bind() (Enlazar │ │ bind() (Puerto │
│ Puerto Conocido) │ │ Efémero / Opcional) │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
┌──────────▼───────────┐ Mensaje en Red ┌──────────▼───────────┐
│ recvfrom() (Espera │ <───────────────────────── │ sendto() (Envía │
│ Datagrama) │ │ Datagrama) │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
│ Mensaje en Red │
│ ─────────────────────────────────────────> │
┌──────────▼───────────┐ ┌──────────▼───────────┐
│ sendto() (Responde) │ │ recvfrom() (Espera │
└──────────┬───────────┘ │ Respuesta) │
│ └──────────┬───────────┘
┌──────────▼───────────┐ ┌──────────▼───────────┐
│ close() (Cerrar) │ │ close() (Cerrar) │
└──────────────────────┘ └──────────────────────┘
PROCESO SERVIDOR PROCESO CLIENTE
┌──────────────────────┐ ┌──────────────────────┐
│ ServerSocket(Puerto) │ │ Socket(IP, Puerto) │
└──────────┬───────────┘ └──────────┬───────────┘
│ │
┌──────────▼───────────┐ Handshake TCP ┌──────────▼───────────┐
│ accept() (Bloqueante)│ <─────────────────────────>│ connect() (Inicia │
└──────────┬───────────┘ (SYN -> SYN-ACK -> ACK) │ Conexión) │
│ └──────────┬───────────┘
┌──────────▼───────────┐ │
│ Genera SocketCliente │ │
│ Dedicado │ │
└──────────┬───────────┘ │
│ │
┌──────────▼───────────┐ Canal TCP de Bytes ┌──────────▼───────────┐
│ Crea Hilo Hijo │ <────────────────────────> │ InputStream / │
│ (ManejadorCliente) │ (InputStream/OutputStream) │ OutputStream │
└──────────────────────┘ └──────────┬───────────┘
│ │
┌──────────▼───────────┐ ┌──────────▼───────────┐
│ Retorna a accept() │ │ close() │
│ para nuevo cliente │ └──────────────────────┘
└──────────────────────┘
- El método accept() en un ServerSocket TCP es una operación bloqueante por definición
main) debe limitarse estrictamente a escuchar y aceptar conexiones activas en un bucle continuo (while(true))accept() retorna un nuevo objeto Socket exclusivo para el cliente entrante, el servidor delega la tarea instanciando un hilo de ejecución independiente (usando un nuevo Thread con un Runnable o un pool de hilos de tipo ExecutorService)accept()En un programa o sistema distribuido, la decisión de usar TCP o UDP se define en dos niveles distintos: a nivel de código (en la implementación de la API de red) y a nivel de diseño arquitectónico.
1. ¿Dónde se define en el Código? (Nivel de Implementación en Java)
java.net): A. Si eliges TCP (Orientado a Conexión y Streams):
java.net.* e instanciar las clases específicas para flujos continuos (streams): - En el Servidor: Instancias
ServerSocket. - En el Cliente: Instancias
Socket. - Intercambio: Utilizas flujos de entrada y salida (
InputStreamyOutputStream/BufferedReaderyPrintWriter) para enviar/recibir datos.
// AL INSTANCIAR ServerSocket / Socket DEFINES QUE USAS TCP
ServerSocket servidor = new ServerSocket(5000); //
Socket socketCliente = servidor.accept(); //
B. Si eliges UDP (Sin Conexión y Datagramas):
- Tanto en Cliente como Servidor: Instancias
DatagramSocket. - Intercambio: Empaquetas los bytes de datos junto a la IP y puerto de destino en objetos
DatagramPacket. - Envío/Recepción: Llamas a los métodos
.send(paquete)y.receive(paquete).
// AL INSTANCIAR DatagramSocket / DatagramPacket DEFINES QUE USAS UDP
DatagramSocket socketUDP = new DatagramSocket(6000); //
DatagramPacket paquete = new DatagramPacket(buffer, buffer.length); //
socketUDP.receive(paquete); //
2. ¿Dónde se define en el Diseño? (Criterio Técnico)
| Criterio de Selección | Usas TCP cuando... | Usas UDP cuando... |
| Fiabilidad y Orden | Necesitas garantía de entrega: No te puedes permitir perder ni un solo byte de datos (ej. transferencia de archivos, transacciones, mensajes de chat). | Toleras pérdida ocasional de paquetes: Es más importante que el dato llegue rápido a que llegue completo (ej. streaming de video, voz sobre IP, videojuegos online)[cite: 1]. |
| Sobrecarga (Overhead) | Aceptas la sobrecarga (overhead) del three-way handshake (establecimiento de conexión) y mensajes de confirmación (ACKs)[cite: 1]. | Quieres evitar la sobrecarga de control y minimizar la latencia enviando paquetes directamente[cite: 1]. |
| Control de Flujo | Requieres que la red gestione el control de flujo para no desbordar al receptor[cite: 1]. | Quieres control total del envío de mensajes independientes[cite: 1]. |
3. Casos Especiales en Arquitecturas Distribuidas
- Middleware y RMI / gRPC: Al utilizar librerías de más alto nivel (como Java RMI, gRPC o WebSockets), la librería interna o el framework ya definió por ti el protocolo subyacente (generalmente TCP o HTTP/2 sobre TCP para garantizar que las invocaciones de métodos remotos y serialización de objetos no se pierdan).
- Servidores Híbridos: Tal como se analiza en la materia, un mismo servidor puede soportar múltiples protocolos al mismo tiempo en puertos separados: recibir datos continuos mediante una conexión TCP y recibir alertas o métricas rápidas mediante datagramas UDP en paralelo.


