¿Qué es java.net.Socket y cómo funciona en la programación de redes en Java?

| Última modificación: 2 de enero de 2025 | Tiempo de Lectura: 3 minutos

Nunca me imaginé que yo sería capaz de hacer que dos computadoras “hablaran” entre sí. Fue algo tremendo y emocionante, pues con java.net.Socket logré conectarlas y centrarme por completo en la lógica de la aplicación, sin perder el tiempo en los detalles técnicos. De verdad que fue una de esas veces en las que me sentí orgulloso de mí mismo, por lograr algo tan impresionante. Si tú también lo quieres hacer, te explico fácilmente qué es java.net.Socket y cómo es que funciona para programar redes en Java.

java.net.Socket en Java qué es

¿Qué es java.net.Socket?

Te decía que java.net.Socket es una clase con la que puedes establecer conexiones de red entre dos máquinas. De hecho, es la base para la comunicación cliente-servidor, porque permite el intercambio de datos a través de streams (flujos). Cuando usas un socket, puedes conectar tu aplicación a otra máquina especificando su dirección IP y puerto.

¿Cómo funciona un socket?

Un socket crea una conexión entre dos extremos:

  1. El cliente: Inicia la conexión usando un objeto de tipo Socket.
  2. El servidor: Escucha las conexiones entrantes a través de un ServerSocket.
  3. Una vez conectados, ambos extremos pueden intercambiar datos usando streams.

Métodos clave en java.net.Socket

  • getInputStream(): Este te devuelve un flujo para leer datos del servidor.
  • getOutputStream(): Te proporciona un flujo para enviar datos al servidor.
  • close(): Se encarga de cerrar la conexión del socket.

Creando una conexión cliente-servidor

Chat básico cliente-servidor

Este ejemplo quiero que veas cómo implementar una aplicación sencilla donde un cliente envía mensajes a un servidor.

Servidor: Escucha y recibe mensajes

import java.io.*;
import java.net.*;

public class Servidor {
public static void main(String[] args) {
try (ServerSocket servidor = new ServerSocket(5000)) {
System.out.println("Servidor iniciado. Esperando cliente...");

Socket socket = servidor.accept();
System.out.println("Cliente conectado.");

BufferedReader entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String mensaje;

while ((mensaje = entrada.readLine()) != null) {
System.out.println("Mensaje recibido: " + mensaje);
if ("salir".equalsIgnoreCase(mensaje)) break;
}

entrada.close();
socket.close();
System.out.println("Conexión cerrada.");
} catch (IOException e) {
System.err.println("Error en el servidor: " + e.getMessage());
}
}
}

Cliente: Envía mensajes al servidor

import java.io.*;
import java.net.*;

public class Cliente {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 5000);
PrintWriter salida = new PrintWriter(socket.getOutputStream(), true);
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in))) {

System.out.println("Conectado al servidor. Escribe tu mensaje:");

String mensaje;
while (!(mensaje = teclado.readLine()).equalsIgnoreCase("salir")) {
salida.println(mensaje);
}
} catch (IOException e) {
System.err.println("Error en el cliente: " + e.getMessage());
}
}
}

Ejecútalo así

  1. Ejecuta primero el programa del servidor. Mostrará el mensaje: Servidor iniciado. Esperando cliente….
  2. Luego, ejecuta el programa del cliente. Podrás escribir mensajes que el servidor recibirá y mostrará en su consola.
  3. Escribe “salir” en el cliente para cerrar la conexión.

Ejemplo avanzado: Descargar un archivo

Ahora veamos cómo lo puedes usar en un escenario más complejo: Imagina que necesitas un programa cliente-servidor donde el cliente solicite un archivo y el servidor lo envíe.

Servidor: Enviar un archivo

import java.io.*;
import java.net.*;

public class FileServer {
public static void main(String[] args) {
try (ServerSocket server = new ServerSocket(6000)) {
System.out.println("Servidor de archivos iniciado. Esperando cliente...");
Socket socket = server.accept();

File archivo = new File("archivo.txt");
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(archivo));
OutputStream os = socket.getOutputStream()) {

byte[] buffer = new byte[1024];
int bytesLeidos;
while ((bytesLeidos = bis.read(buffer)) != -1) {
os.write(buffer, 0, bytesLeidos);
}
}

socket.close();
System.out.println("Archivo enviado y conexión cerrada.");
} catch (IOException e) {
System.err.println("Error en el servidor de archivos: " + e.getMessage());
}
}
}

Cliente: Descargar un archivo

import java.io.*;
import java.net.*;

public class FileClient {
public static void main(String[] args) {
try (Socket socket = new Socket("127.0.0.1", 6000);
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream("archivo_descargado.txt")) {

byte[] buffer = new byte[1024];
int bytesLeidos;
while ((bytesLeidos = is.read(buffer)) != -1) {
fos.write(buffer, 0, bytesLeidos);
}

System.out.println("Archivo descargado con éxito.");
} catch (IOException e) {
System.err.println("Error en el cliente de archivos: " + e.getMessage());
}
}
}

Beneficios de usar adecuadamente java.net.Socket

  • Simplicidad: Algo grandioso es que abstrae los detalles complejos del protocolo TCP.
  • Versatilidad: Te servirá bastante para aplicaciones en tiempo real como chats, juegos y transferencia de archivos.
  • Escalabilidad: Recuerda que puedes combinar sockets con hilos para manejar múltiples clientes.

Ahora sabes que con java.net.Socket, puedes construir aplicaciones complejas y flexibles que aprovechen el poder de las redes. En serio te digo que es una clase fundamental para programar redes en Java, aprovecha que ya sabes establecer la comunicación básica y transferir datos para que trabajes en proyectos más elaborados.

¿Quieres continuar mejorando tus habilidades? ¿Sientes que lo tuyo es la programación? Únete al Bootcamp de Java Full Stack de KeepCoding y aprende no solo sockets, sino todas las herramientas necesarias para convertirte en un desarrollador completo. ¡Inscríbete hoy mismo y transforma tu futuro!

Posts más leídos