¡Recomienda este blog!

viernes, 4 de noviembre de 2011

Cliente - Servidor de réplica (TCP) en Java

En esta entrada se pretende explicar de una forma práctica y lo más sencilla posible, como se ha de implementar un Cliente-Servidor de réplica usando Java RMI. Para ello utilizaremos la API Java que se encarga de gestionar el protocolo TCP. Así, como el paquete java.net, donde podemos encontrar la especificación completa de las clases involucradas.

Para el desarrollo de la aplicación cliente/servidor con TCP, primero debemos implementar la clase Connection, que permite realizar una conexión diferenciada para cada cliente. Lo podemos introducir en el mismo paquete donde después se creará el servidor. El código es el siguiente.


package paqueteTCPServer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Iván Durango
 */
class Connection extends Thread{

    // Instanciamos los fuljos de datos de entrada y salida,y el socket para
    // conexión.
    DataInputStream in;
    DataOutputStream out;
    Socket clientSocket;

    // Constructor.
    public Connection(Socket aSocket){
        
        // Asocia el Socket(this) con el del cliente que conecta.
        clientSocket = aSocket;
        
        try {
            
            // Creamos los flujos de entrada y salida de datos, y lo se los 
            // asociamos al socket cliente.
            in = new DataInputStream(clientSocket.getInputStream());
            out = new DataOutputStream(clientSocket.getOutputStream());
        
        } catch (IOException ex) {
            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("Error en conexion: " + ex.getMessage());
        }
        
        // Lanzamos el método run.
        this.start();
    }

    public void run(){
        
        try {
                        
            String data;
            
            // Recibe los datos mandados por el cliente.
            data = in.readUTF();
            
            // Realiza la réplica de los datos + un ACK.
            out.writeUTF("Servidor TCP,OK! " + data);
            
        // Control de excepciones.
        } catch (IOException ex) {
            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Tras esto se implementa el servidor:

package paqueteTCPServer;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 *
 * @author Iván Durango
 */

public class TCPServer{

    public static void main(String args[]){

        // Establecemos el número de puerto a utilizar.
        int serverPort = 7896;
        
        // Creamos una instancia para esperar las peticiones de los clientes.
        ServerSocket listenSocket;
        
        // Socket para conexión.
        Socket clientSocket;

        // Usamos la clase conection.
        Connection c;

        try{
            
            // Creamos el objeto para esperar peticiones de los clientes.
            listenSocket = new ServerSocket(serverPort);

            while (true){
                
                // Dejamos invocado el servidor esperando haste que un cliente
                //se conecte. clientSocket = Socket nuevo para comunicaciones.
                clientSocket = listenSocket.accept();
                
                // Se establece la conexión, y se vuelve a esperar un nuevo cliente.
                c = new Connection(clientSocket);
            }
            
        // Control de excepciones.
        }catch(IOException e){
            System.out.println("Error en socket: " + e.getMessage());
        }
    }
}

Una vez desarrollado el c odigo del servidor, desarrollamos el correspondiente cliente TCP:

package paqueteTCPClient;

// Se importan los paquetes necesarios.

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Iván Durango Blanco
 */

public class TCPClient {

    // Función principal de la clase.
    public static void main(String args[]){
        
        // Creamos una instancia a null, de la clase socket.        
        Socket s = null;
        
        // Establecesmos el puerto a utilizar en la variable serverPort.
        int serverPort = 7896;
        
        // Creamos una instancia para un flujo de entrada de datos.
        DataInputStream in;
        
        // Creamos una instancia para un fujo de salida de datos.
        DataOutputStream out;

        // data almacena los datos a enviar.
        String data;

        try {
            
            // Creamos un nuevo Socket, con el nombre de host pasado por argumento
            // y con el puerto establecido anteriormente.
            s = new Socket(args[1], serverPort);
            
            // Creamos un nuevo flujo de entrada de datos usando el socket creado.
            in = new DataInputStream(s.getInputStream());
            
            // Creamos un nuevo flujo de salida de datos usando el socket creado.
            out = new DataOutputStream(s.getOutputStream());
            
            // Escribimos en la tubería de datos el mensaje pasado como argumento.
            out.writeUTF(args[0]);
            
            // Obtiene la respuesta del servidor.
            data = in.readUTF();
            
            // Se muestra por pantalla.
            System.out.println("Datos recibidos: " +data+"\n");
        
        // Control de excepciones.
        } catch (UnknownHostException ex) {
            Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("\nHost no encontrado");
        } catch (IOException ex) {
            Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Para probar que el código funciona, se relizan conexiones en "localhost" y en remoto. Para ello es necesario introducirle al cliente los argumentos necesarios. Antes de nada, deciros que los pasos comentados son válidos solo si se usa NetBeans como entorno de desarrollo. Son los siguientes:

Nos vamos a Run --> Set project configuration --> Customize y dentro de la pestaña run, en la sección arguments introducimos los siguiente:

  • Para conectar en local introducimos:"hola que ta,Soy Iván!", localhost.
  • Para Conectar en remoto:"hola que ta,Soy Iván!", NombreHostServerRemoto.

0 comentarios:

Publicar un comentario