Clase Socket de Java

Socket es el bloque de construcción básico de la comunicación en red; permite el intercambio de datos entre diferentes computadoras a través de la red.

En Java,java.net.Socketla clase proporciona la funcionalidad de cliente para implementar la comunicación en red.

Puedes imaginar Socket como una conexión entre dos teléfonos:

  • Un extremo es el cliente (la persona que llama)
  • El otro extremo es el servidor (la persona que contesta)
  • Una vez establecida la conexión, ambas partes pueden enviarse y recibir información mutuamente.

Uso básico de la clase Socket

Crear una conexión Socket

Para crear una conexión Socket, necesitas especificar la dirección y el puerto del servidor:

Ejemplo

try {
    // Conectar al puerto 8080 de localhost
    Socket socket = new Socket("localhost", 8080);
   
    // Usar el socket para comunicarse...
   
    // Cerrar la conexión
    socket.close();
} catch (IOException e) {
    e.printStackTrace();
}

Métodos principales

La clase Socket proporciona varios métodos importantes:

Método Descripción
getInputStream() Obtiene el flujo de entrada para recibir datos.
getOutputStream() Obtiene el flujo de salida para enviar datos.
close() Cierra la conexión Socket.
isConnected() Verifica si la conexión está establecida.
setSoTimeout(int timeout) Establece el tiempo de espera (milisegundos).

Implementar comunicación cliente-servidor

Ejemplo de cliente

Ejemplo

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

public class Client {
    public static void main(String[] args) {
        try {
            // 1. Crear la conexión Socket
            Socket socket = new Socket("localhost", 12345);
           
            // 2. Obtener el flujo de salida, enviar datos al servidor
            PrintWriter out = new PrintWriter(
                socket.getOutputStream(), true);
            out.println("Hello Server!");
           
            // 3. Obtener el flujo de entrada, recibir la respuesta del servidor
            BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
            String response = in.readLine();
            System.out.println("Server response: " + response);
           
            // 4. Cerrar la conexión
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Ejemplo de servidor

El lado del servidor necesita usarServerSocketla clase:

Ejemplo

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

public class Server {
    public static void main(String[] args) {
        try {
            // 1. Crear ServerSocket, escuchando en el puerto especificado
            ServerSocket serverSocket = new ServerSocket(12345);
            System.out.println("Server started. Waiting for client...");
           
            // 2. Esperar la conexión del cliente
            Socket clientSocket = serverSocket.accept();
            System.out.println("Client connected.");
           
            // 3. Obtener el flujo de entrada, leer el mensaje del cliente
            BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
            String message = in.readLine();
            System.out.println("Client says: " + message);
           
            // 4. Obtener el flujo de salida, enviar la respuesta al cliente
            PrintWriter out = new PrintWriter(
                clientSocket.getOutputStream(), true);
            out.println("Hello Client!");
           
            // 5. Cerrar la conexión
            clientSocket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Características avanzadas de Socket

Establecer tiempo de espera (timeout)

Ejemplo

Socket socket = new Socket();
// Establecer el tiempo de espera de conexión a 5 segundos
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// Establecer el tiempo de espera de lectura a 3 segundos
socket.setSoTimeout(3000);

Mantener la conexión

Ejemplo

// Habilitar el mecanismo TCP keep-alive
socket.setKeepAlive(true);

Tamaño del búfer

Ejemplo

// Establecer el tamaño del búfer de recepción (bytes)
socket.setReceiveBufferSize(8192);
// Establecer el tamaño del búfer de envío (bytes)
socket.setSendBufferSize(8192);

Problemas comunes y soluciones

Conexión rechazada

  • Verificar si el servidor se está ejecutando
  • Confirmar que el número de puerto sea correcto
  • Verificar la configuración del firewall

Tiempo de espera de conexión agotado

  • Verificar la conexión de red
  • Aumentar el tiempo de espera
  • Confirmar que la dirección del servidor sea correcta

Recepción de datos incompleta

  • Asegurarse de que ambas partes usen el mismo protocolo
  • Verificar que el tamaño del búfer sea suficiente
  • Considerar el uso de delimitadores o mensajes de longitud fija

Escenarios de aplicación práctica

La programación con Socket tiene amplias aplicaciones en la práctica:

  • Aplicaciones de mensajería instantánea (como WeChat, QQ)
  • Juegos en línea
  • Software de control remoto
  • Herramientas de transferencia de archivos
  • Comunicación de dispositivos IoT (Internet de las cosas)

Mejores prácticas

  1. Manejar siempre las excepciones de E/S
  2. Usar try-with-resources para asegurar la liberación de recursos
  3. Establecer tiempos de espera razonables para operaciones importantes
  4. Considerar el uso de un pool de hilos para manejar múltiples conexiones
  5. Diseñar un protocolo de comunicación claro
Otras extensiones