Comunicación cliente-servidor en Java

Sencillos pasos para transferir datos entre un cliente y un servidor en Java mediante el protocolo TCP

En este tutorial se mostrará cómo se pueden comunicar dos programas executados en distintos equipos mediante sockets utlizando Java.

Un socket (o puerto) es un punto de comunicación entre sistemas que corresponde al dispositivo físico d'entrada/salida de una máquina. Bàsicamente, existen dos tipos de protocolos para establecer conexiones entre varios equipos: TCP y UDP.

TCP, (Transmission Control Protocol) y UDP (User Datagram Protocol). Para entendernos, TCP es un protocolo en el que hay un proceso de negociación (handshaking) entre los afectados cliente y servidor y de cómo se envían los datos, si se han recibido bien, etc. Mientras que UDP es un servicio en el que los datos se van enviando y recibiendo sin ese acuerdo. De forma que UDP es un sistema de comunicación más rápido en una red en la que se pierdan pocos paquetes.

En este caso utilizaremos el protocolo TCP para crear un servidor y un cliente que se comuniquen.

Cliente

En el código del cliente al crear el socket debemos especificar a qué ip nos conectaremos y a qué puerto. Hay algunos puertos reservados por lo que siempre miraremos de escoger uno bastante alto. En este caso 10831.

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Cliente {

    public static void main(String[] args) {
        try {
            Socket canalComunicacion = null;
            OutputStream bufferSalida;
            DataOutputStream datos;
            canalComunicacion = new Socket("127.0.0.1", 10831);
            bufferSalida = canalComunicacion.getOutputStream();
            datos = new DataOutputStream(bufferSalida);
            String mensaje = "Hola Mundo!\\n";
            for (int i = 0; i < 10; i++) {
                datos.writeUTF(mensaje);
            }
            datos.writeUTF("");
            datos.close();
            bufferSalida.close();
            canalComunicacion.close();
        } catch (UnknownHostException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Cliente.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
}

Servidor

Para que el cliente encuentre el servidor hay que especificar el mismo puerto.

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Servidor {

    public static void main(String[] args) {
        try {
            ServerSocket puerto = null;
            Socket canalComunicacion = null;
            InputStream bufferEntrada;
            DataInputStream datos;
            puerto = new ServerSocket(10831);
            canalComunicacion = puerto.accept();
            bufferEntrada = canalComunicacion.getInputStream();
            datos = new DataInputStream(bufferEntrada);
            String cadena = new String(datos.readUTF());
            while (cadena.length() > 0) {
                System.out.print(cadena);
                cadena = datos.readUTF();
            }
            datos.close();
            bufferEntrada.close();
            canalComunicacion.close();
        } catch (IOException ex) {
            Logger.getLogger(Servidor.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Finalmente para ver que hay una comunicación procedemos a ejecutar el servidor y luego el cliente. Veremos que se imprimirá por pantalla la cadena pasada por el cliente sólo si el servidor se está ejecutando.