taller 2 inet 2017

Servidor Múltiple

En el ejemplo anterior el servidor sólo atiende un cliente, normalmente lo que queremos es que el servidor atienda a todos los clientes que requieran servicio, incluso que los pueda atender en forma simultánea. para lograr esto cambiaremos la codificación del servidor (el cliente lo dejamos igual) y haremos uso de hilos que es la manera apropiada de atacar estos problemas

En el servidor tendremos un hilo principal el cual estará escuchando por peticiones de conexión, y cada vez que llegue una petición arrancaremos otro hilo que la atienda, suena muy fácil, con Java lo es!. Así es que vamos a ver que tenemos que hacer, el archivo se llama ServidorM2.java, la M es de múltiple.

El hilo principal, dentro el main, sólo escucha por peticiones de conexión, y una vez que llega una, además de imprimir algunos datos del cliente (dirección IP y puerto), crea un ejemplar de la clase Atiende que es la que atenderá a un cliente dentro de un hilo. habrá tantos ejemplares de Atiende como clientes se conecten. Además puedes ver que el parámetro del constructor de Atiende es el socket correspondiente a la conexión que se acaba de aceptar. La variable escuchando es la que determina si el programa sigue escuchando por peticiones de conexión, en este caso escuchando nunca se hace false, así es que este programa siempre estará corriendo independiente de la cantidad de clientes que haya

ServerSocket yo = null;
Socket cliente = null;
boolean escuchando = true;         
yo = new ServerSocket(5000);
while(escuchando){
      cliente = yo.accept();
      System.out.println("Ya se conecto un cliente desde: " + 
                          cliente.getInetAddress().getHostName() + 
                         "("+cliente.getPort()+")");
      new Atiende(cliente).start();
}
yo.close();

Ahora veamos la clase Atiende, realmente lo único que hicimos fué pasar todo lo que se necesita para atender a un cliente dentro del método run(), el cual como recuerdas de la lección de hilos del curso pasado, es el que se comienza a ejecutar cuando llamamos a start()

Primero veamos el constructor. Lo que hacemos es guardar una referencia al cliente que se conectó esto lo guardamos en un socket cliente, y en la variable String nombreyDirIP guardamos la dirección IP de la máquina remota, es decir la del cliente, para simplemente imprimir su valor cada vez que llegue un string de ese cliente, para poder distinguirlo en la impresión del servidor. Recuerda que la clase Atiende debe de extender a Thread para que un ejemplar de esa clase tenga los atributos de un hilo

public Atiende(Socket cliente){
     this.cliente = cliente;
     nombreyDirIP = this.cliente.getInetAddress().toString();
}

Veamos el método run() de la clase atiende, realmente no requiere ninguna explicación ya que el código es idéntico al ejemplo anterior, la única diferencia es que lo pusimos en un hilo

public void run(){
  entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));
  salida = new DataOutputStream(cliente.getOutputStream());         
  do{
     llego = entrada.readLine();
     System.out.println("("+nombreyDirIP+") Llego: "+ llego);
     salida.writeInt(llego.length());
  }while(llego.length()!=0);
  entrada.close();
  cliente.close();
  System.out.println("Ya se desconecto"+"("+nombreyDirIP+")");
}

Como ves fué bastante fácil hacer que el servidor se comportara como un servidor real. GRACIAS JAVA!

El cliente no se modificó en lo absoluto, de hecho es el mismo y obviamente se ejecuta de la misma manera, a continuación hay una corrida del servidor con varios clientes, tu puedes hacer la prueba en tu máquina

 

Cliente2A.java

Como último ejemplo vamos a codificar un cliente desde un applet. Como saben un applet está sometido a restricciones de seguridad (por razones obvias), una de esas restricciones es que un applet no puede abrir conexiones de red con máquinas en forma indiscriminada. Sólo puede abrir conexiones de red con la máquina desde donde se bajó el applet. Para que nuestro ejemplo funcione tenemos que poner a correr el mismo servidor (ServidorM2) en una máquina que tenga servidor de Web. Veamos lo relevante de este applet, es importante que entendamos el funcionamiento porque, tomando este ejemplo como base, harán su primer ejercicio del curso, así es que mucha atención. El archivo Cliente2A.java además lo puedes encontrar con los otros archivos que bajaste

Comenzaremos con la ejecución del applet para que entendamos el código de mejor manera, no te olvides que en el servidor de Web de donde baje el applet está corriendo nuestro servidor ServidorM2

Al cargar el applet aparece lo siguiente

El siguiente paso es teclear algo en el textfield y presionar el botón Envía, en ese momento se manda al servidor el string que se tecleo y el servidor contesta con el entero que el applet

al recibirlo, lo imprime en el segundo textfield, quedando lo siguiente

El código y el análisis está en Cliente2A.java



Comments