Introducción
En este tema, aprenderemos sobre ServerSocket
, una clase fundamental en Java para la creación de aplicaciones de red que actúan como servidores. Un ServerSocket
espera conexiones entrantes de clientes y establece una comunicación bidireccional con ellos.
Conceptos Clave
- ServerSocket: Una clase que implementa un servidor de sockets. Permite que una aplicación acepte conexiones de clientes.
- Socket: Una clase que representa una conexión de red entre dos máquinas.
- Puerto: Un número que identifica un proceso específico en una máquina. Los puertos permiten que múltiples servicios de red se ejecuten simultáneamente en una sola máquina.
Creación de un ServerSocket
Para crear un ServerSocket
, necesitas especificar un puerto en el que el servidor escuchará las conexiones entrantes. Aquí hay un ejemplo básico:
import java.io.*; import java.net.*; public class SimpleServer { public static void main(String[] args) { int port = 1234; // Puerto en el que el servidor escuchará try (ServerSocket serverSocket = new ServerSocket(port)) { System.out.println("Servidor escuchando en el puerto " + port); // Espera a que un cliente se conecte Socket clientSocket = serverSocket.accept(); System.out.println("Cliente conectado"); // Flujo de entrada para recibir datos del cliente BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // Flujo de salida para enviar datos al cliente PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("Recibido: " + inputLine); out.println("Echo: " + inputLine); // Envía una respuesta al cliente } } catch (IOException e) { System.out.println("Error en el servidor: " + e.getMessage()); } } }
Explicación del Código
- Importaciones: Importamos las clases necesarias para manejar la entrada/salida y la red.
- Creación del ServerSocket: Creamos un
ServerSocket
que escucha en el puerto 1234. - Aceptación de Conexiones: El método
accept()
espera hasta que un cliente se conecte y devuelve unSocket
para la comunicación. - Flujos de Entrada y Salida: Utilizamos
BufferedReader
para leer datos del cliente yPrintWriter
para enviar datos al cliente. - Bucle de Comunicación: Leemos líneas de texto del cliente y enviamos una respuesta de eco.
Ejercicio Práctico
Ejercicio 1: Crear un Servidor de Eco
Objetivo: Crear un servidor que reciba mensajes de un cliente y los devuelva (eco).
Instrucciones:
- Crea una clase
EchoServer
. - Configura un
ServerSocket
en el puerto 5678. - Acepta conexiones de clientes.
- Lee mensajes del cliente y envíalos de vuelta.
Solución:
import java.io.*; import java.net.*; public class EchoServer { public static void main(String[] args) { int port = 5678; try (ServerSocket serverSocket = new ServerSocket(port)) { System.out.println("EchoServer escuchando en el puerto " + port); while (true) { Socket clientSocket = serverSocket.accept(); System.out.println("Cliente conectado"); BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("Recibido: " + inputLine); out.println("Echo: " + inputLine); } } } catch (IOException e) { System.out.println("Error en el servidor: " + e.getMessage()); } } }
Ejercicio 2: Crear un Cliente para el Servidor de Eco
Objetivo: Crear un cliente que se conecte al EchoServer
y envíe mensajes.
Instrucciones:
- Crea una clase
EchoClient
. - Conéctate al servidor en
localhost
y puerto 5678. - Envía mensajes al servidor y muestra las respuestas.
Solución:
import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) { String hostname = "localhost"; int port = 5678; try (Socket socket = new Socket(hostname, port)) { PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("Respuesta del servidor: " + in.readLine()); } } catch (UnknownHostException e) { System.err.println("No se conoce el host " + hostname); } catch (IOException e) { System.err.println("Error de I/O en la conexión con " + hostname); } } }
Resumen
En esta lección, hemos aprendido a:
- Crear un
ServerSocket
para aceptar conexiones de clientes. - Utilizar
Socket
para la comunicación bidireccional. - Implementar un servidor de eco simple y un cliente que se conecta a él.
Con estos conocimientos, estás preparado para construir aplicaciones de red más complejas en Java. En la siguiente lección, exploraremos DatagramSocket
y DatagramPacket
para la comunicación basada en UDP.
Curso de Programación en Java
Módulo 1: Introducción a Java
- Introducción a Java
- Configuración del Entorno de Desarrollo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Operadores
Módulo 2: Flujo de Control
Módulo 3: Programación Orientada a Objetos
- Introducción a la POO
- Clases y Objetos
- Métodos
- Constructores
- Herencia
- Polimorfismo
- Encapsulamiento
- Abstracción
Módulo 4: Programación Orientada a Objetos Avanzada
Módulo 5: Estructuras de Datos y Colecciones
Módulo 6: Manejo de Excepciones
- Introducción a las Excepciones
- Bloque Try-Catch
- Throw y Throws
- Excepciones Personalizadas
- Bloque Finally
Módulo 7: Entrada/Salida de Archivos
- Lectura de Archivos
- Escritura de Archivos
- Flujos de Archivos
- BufferedReader y BufferedWriter
- Serialización
Módulo 8: Multihilo y Concurrencia
- Introducción al Multihilo
- Creación de Hilos
- Ciclo de Vida de un Hilo
- Sincronización
- Utilidades de Concurrencia
Módulo 9: Redes
- Introducción a las Redes
- Sockets
- ServerSocket
- DatagramSocket y DatagramPacket
- URL y HttpURLConnection