Implementación de Sockets en Java: Ejemplos Prácticos de Servidores y Clientes
Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones
Escrito el en
español con un tamaño de 8,84 KB
Implementación de Sockets en Java
A continuación, se presentan diversos ejemplos prácticos para la comunicación entre procesos mediante Sockets en Java, cubriendo desde un juego simple hasta un servidor web básico.
1. Juego de Adivinanza: Cliente y Servidor
Este ejemplo ilustra una comunicación síncrona donde el cliente intenta adivinar un número generado por el servidor.
Código del Cliente (AdivinaCliente)
public class AdivinaCliente {
public static final int PORT = 4444;
public static void main(String[] args) {
Socket socketCliente = null;
BufferedReader entrada = null;
PrintWriter salida = null;
try {
socketCliente = new Socket("127.0.0.1", PORT);
entrada = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
salida = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socketCliente.getOutputStream())), true);
} catch (ConnectException e) {
System.err.println("¿Hay alguien al otro lado? No se pudo conectar con el servidor.");
System.exit(-1);
} catch (IOException e) {
System.err.println("No se pudieron abrir los pipes de E/S.");
System.exit(-2);
}
Scanner sc = new Scanner(System.in);
String linea;
try {
System.out.print("Elige dificultad (facil, media, dificil): ");
linea = sc.nextLine();
if (!linea.equals("facil") && !linea.equals("media") && !linea.equals("dificil")) {
System.out.println("No has introducido una dificultad válida.");
} else {
salida.println(linea);
System.out.println("Vamos allá. Para rendirte escribe \"Rendirse\"");
while (true) {
System.out.print("¿Qué número crees que es? ");
linea = sc.nextLine();
if (linea.equals("Rendirse")) {
salida.println("GIVEUP");
System.out.println("¡El número era " + entrada.readLine() + "!");
break;
}
try {
Integer.parseInt(linea);
salida.println(linea);
String resultado = entrada.readLine();
if (resultado.equals("GREATER")) {
System.out.println("No... es mayor.");
} else if (resultado.equals("LOWER")) {
System.out.println("No... es menor.");
} else if (resultado.equals("EQUAL")) {
System.out.println("¡Acertaste!");
break;
} else {
System.out.println("Respuesta inesperada del servidor: " + resultado);
}
} catch (NumberFormatException e) {
System.out.println("No has introducido un número válido.");
}
}
}
salida.close();
entrada.close();
sc.close();
socketCliente.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}Código del Servidor (AdivinaServidor)
public class AdivinaServidor {
public static final int PORT = 4444;
public static void main(String[] args) {
ServerSocket socketServidor = null;
try {
socketServidor = new ServerSocket(PORT);
} catch (IOException e) {
System.out.println("No puede escuchar en el puerto: " + PORT);
System.exit(-1);
}
Socket socketCliente = null;
BufferedReader entrada = null;
PrintWriter salida = null;
try {
socketCliente = socketServidor.accept();
entrada = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
salida = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socketCliente.getOutputStream())), true);
System.out.println("Servidor iniciado.");
int max;
switch (entrada.readLine()) {
case "facil": max = 10; break;
case "media": max = 100; break;
default: max = 1000; break;
}
int numeroSecreto = new Random().nextInt(max + 1);
System.out.println("Número secreto: " + numeroSecreto);
String leido;
while (true) {
leido = entrada.readLine();
if (leido.equals("GIVEUP")) {
salida.println(numeroSecreto);
break;
}
int numeroJugador = Integer.parseInt(leido);
if (numeroSecreto > numeroJugador) {
salida.println("GREATER");
} else if (numeroSecreto < numeroJugador) {
salida.println("LOWER");
} else {
salida.println("acertado");
break;
}
}
System.out.println("Servidor detenido");
salida.close();
entrada.close();
socketCliente.close();
socketServidor.close();
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
}
}
}2. Servidor Multihilo (Eco)
Para manejar múltiples clientes simultáneamente, utilizamos Threads (hilos).
Clase Worker (ClientWorker)
class ClientWorker extends Thread {
Socket socketCliente;
public ClientWorker(Socket socketCliente) {
this.socketCliente = socketCliente;
}
@Override
public void run() {
BufferedReader entrada = null;
PrintWriter salida = null;
try {
entrada = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
salida = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socketCliente.getOutputStream())), true);
while (true) {
String str = entrada.readLine();
if (str == null) {
System.out.println("Cliente desconectado.");
break;
}
salida.println(str);
if (str.equals("Fin")) break;
}
salida.close();
entrada.close();
socketCliente.close();
} catch (IOException e) {
System.out.println("No se pudieron abrir los streams de I/O para el cliente");
}
}
}Servidor Principal (EcoServidorMultihilo)
public class EcoServidorMultihilo {
public static final int PORT = 4444;
public static void main(String[] args) throws IOException {
ServerSocket socketServidor = new ServerSocket(PORT);
while (true) {
Socket socketCliente = socketServidor.accept();
System.out.println("Cliente conectado: " + socketCliente);
new ClientWorker(socketCliente).start();
}
}
}3. Servidor Web Básico
Un ejemplo sencillo de cómo un servidor puede servir archivos estáticos mediante el protocolo HTTP.
public class ServidorWeb {
public static final int PORT = 8080;
public static void main(String[] args) throws IOException {
ServerSocket socketServidor = new ServerSocket(PORT);
while (true) {
try (Socket socketCliente = socketServidor.accept()) {
BufferedReader entrada = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
PrintWriter salida = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socketCliente.getOutputStream())), true);
String str = entrada.readLine();
if (str == null) continue;
String[] partes = str.split(" ");
String recurso = partes[1];
File archivo = new File("." + recurso);
if (archivo.exists() && !archivo.isDirectory()) {
byte[] contenidoBytes = Files.readAllBytes(archivo.toPath());
salida.println("HTTP/1.1 200 OK");
salida.println("Content-Type: text/html; charset=UTF-8");
salida.println("Content-Length: " + contenidoBytes.length);
salida.println();
Files.copy(archivo.toPath(), socketCliente.getOutputStream());
} else {
salida.println("HTTP/1.1 404 Not Found");
}
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
}
}
}
}