====== 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.