====== 01 - Sockets TCP ======
Un **socket** es el punto de comunicación de un programa en la red: combina una dirección **IP** (la máquina) y un **puerto** (la aplicación que escucha en ella). Con sockets TCP dos programas intercambian un flujo de bytes ordenado y fiable.
===== 1. Cliente y servidor =====
@startuml
participant "Servidor" as S
participant "Cliente" as C
S -> S : ServerSocket(8080) y accept()
C -> S : Socket("localhost", 8080)
note right of S : accept() devuelve el\nSocket de esa conexión
S <-> C : flujos de entrada y salida
C -> S : cierra la conexión
S -> S : vuelve a accept()
@enduml
* El **servidor** crea un ''ServerSocket'' en un puerto y se queda esperando en ''accept()''.
* Cada conexión aceptada devuelve un ''Socket'' con los flujos de entrada y salida.
* El **cliente** se conecta con ''new Socket(host, puerto)''.
===== 2. Servidor eco =====
public class EchoServer {
public static void main(String[] args) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(8080)) {
while (true) {
try (Socket socket = serverSocket.accept()) {
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String line;
while ((line = in.readLine()) != null) {
out.println("ECHO: " + line);
}
}
}
}
}
}
public class EchoClient {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 8080);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
out.println("hola");
System.out.println(in.readLine()); // ECHO: hola
}
}
}
El servidor repite lo que recibe hasta que el cliente cierra la conexión.
===== 3. Un protocolo de aplicación =====
Un socket solo transmite bytes; el **protocolo** es el acuerdo sobre cómo se organizan: dónde termina cada mensaje, qué significa cada línea, en qué orden se envían. El protocolo HTTP es un ejemplo: define la petición y la respuesta exactamente con ese tipo de reglas.
===== 4. Servidor secuencial =====
El servidor anterior atiende **una conexión a la vez**: mientras habla con un cliente, los demás esperan en ''accept()''.
Cliente A ── conecta ──> [ atendido ]
Cliente B ── conecta ──> [ esperando ]...
Esta limitación es la motivación del siguiente tema: con **hilos**, cada conexión puede atenderse en paralelo.
Cierra siempre los sockets y flujos (aquí con ''try-with-resources''). Una conexión sin cerrar deja recursos ocupados en ambos extremos.