ClubEnsayos.com - Ensayos de Calidad, Tareas y Monografias
Buscar

Aplicación cliente-servidor lectura unidad 2

Lili MonterrosaDocumentos de Investigación9 de Agosto de 2018

7.436 Palabras (30 Páginas)179 Visitas

Página 1 de 30

[pic 1]

Aplicación Cliente/Servidor

Vamos a desarrollar una pequeña aplicación de comunicación en redes, la haremos del tipo Cliente/Servidor, a veces cuando tenemos aplicaciones de este tipo es difícil distinguir que parte de la aplicación es el cliente y cual el servidor, en nuestro caso será fácil darse cuenta de cual es cual. Normalmente el cliente es que inicia la comunicación pidiendo un servicio y el servidor es el que provee ese servicio.

La comunicación entre ambas partes además de tener como infraestructura sockets de TCP/IP tiene que tener un protocolo particular, este protocolo es que marca el orden de la transmisión de los datos y el tipo de estos datos, para que coincida el tipo de datos que una de las entidades manda y el tipo de datos que la otra espera recibir, esto es muy importante porque si no se respeta la aplicación no sirve para nada, además de que contendrá una serie de errores.

Esquema de un Servidor

  1. Abrir un socket (ServerSocket) para esperar por peticiones de conexión
  2. Al llegar una petición, crear otro socket (Socket) por medio del cual se comunicará con el cliente
  3. Asociar uno o más flujos intermedios a los flujos de entrada (InputStream) y de salida (OutputStream) asignados al socket 
  4. Leer/Escribir a los flujos de acuerdo al protocolo establecido
  5. Eventualmente termina la comunicación
  6. Cerrar flujos y sockets 

Esquema del Cliente

  1. Abrir un socket (Socket) para conectarse y comunicarse con el Servidor
  2. Establecer conexión con el Servidor
  3. Asociar uno o más flujos intermedios a los flujos de entrada (InputStream) y de salida (OutputStream) asignados al socket
  4. Leer/Escribir a los flujos de acuerdo al protocolo establecido
  5. Eventualmente termina la comunicación
  6. Cerrar flujos y sockets

Ejemplo2

En nuestro ejemplo el cliente enviará strings al Servidor y este le contestará con la longitud del string recibido, algo que nos dará una idea del poder de Java es que por medio de flujos (streams), lo que el cliente mandará será literalmente un String y no un grupo de bytes, y lo más interesante es que el Servidor contestará con un entero (int) no con un par de bytes que habría que transformar para poder manejarlo como un entero. Lo anterior se puede lograr por el uso de flujos en Java que nos permite subir el nivel de abstracción de nuestra programación, generando programas más legibles y mantenibles.

Ambos programas terminan cuando el cliente envía un string nulo al Servidor, además el cliente debe dar la dirección IP del servidor en la línea de comandos, para poder correr los programas en cualquier máquina sin necesidad de cambiar la dirección delservidor y volver a compilar, así es que adelante!

Te recomiendo que tengas a mano el código de cada programa porque veremos sólo el código relevante, los puedes ver en Servidor2.java y Cliente2.java .

Servidor2.java

Delcaración de las variables utilizadas:

ServerSocket yo = null; // Socket para escuchar por peticiones de conexión

Socket cliente = null;  // Socket para comunicarse con el cliente, recibir

                           el string y mandar el entero

BufferedReader entrada; // flujo para poder leer del socket un string,

                           con el método readline()

DataOutputStream salida;// flujo para poder mandar un entero al cliente

                           con el método writeInt()

String llego;                          // El string donde se almacenará el string

                           recibido del cliente

 

Crear el socket para escuchar por peticiones de conexión en el puerto 5000 y ponerlo a escuchar, cuando haya una petición asignar el socket para conexión al socket cliente.

yo = new ServerSocket(5000);

cliente = yo.accept();


Asignar los flujos de entrada y salida al
socket cliente para poder leer y escribir, aquí la cosa se pone bastante interesante. Para leer un string mandado por el cliente lo queremos hacer con readline() que me regresa directamente un string, no nos gustaría usar readline() de ObjectInputStream porque está desaprobado (deprecated), esto nos deja con readline() de la clase BufferedReader que es el adecuado porque procesa perfectamente los carácteres en Unicode, si vemos en la documentación el constructor de BufferedReader necesita como parámetro un Reader que es superclase de InputStreamReader el cual acepta en su constructor como parámetro un InputStream que es el tipo flujo que se le asigna a un socket por default, estas son las razones para hacer el encadenamiento de flujos que ves en el código, en este caso nos da la ventaja de leer directamente un string en lugar de leer una secuencia de bytes y transformarlo a string, lo cual se puede hacer y lo haremos más adelante con datagramas, pero definitivamente es más conveniente este enfoque.

De la misma manera nos gustaría poder escribir al socket un entero en lugar de mandar los bytes y que los procese el cliente, para esto necesitamos un DataOutputStream que tiene el método writeInt(), aquí la cosa está más directa porque el contructor de DataOutputStream acepta directamente un OutputStream que es el tipo de flujo que se le asigna a un socket por default.

entrada = new BufferedReader(new InputStreamReader(cliente.getInputStream()));

salida = new DataOutputStream(cliente.getOutputStream());

Después de establecer todo lo necesario para la comunicación, tenemos que realizar nuestro intercambio de datos entre el cliente y el servidor, recordemos que el cliente enviará un string y el servidor le mandará la longitud del string recibido, esto se hará en forma cíclica hasta que el cliente mande un string nulo.

do{

   llego = entrada.readLine();

   System.out.println("Llego: " + llego);

   salida.writeInt(llego.length());

}while(llego.length()!=0);

Finalmente cuando se termina el ciclo, lo único que nos queda es cerrar los flujos y los sockets.

entrada.close();

cliente.close();

yo.close();

Cliente2.java

El cliente, después de conectarse con el servidor, leerá del teclado un string dado por el usuario y se lo mandará al servidor, para después leer un entero que debe ser la longitud del string que acaba de mandar.

Declaración de las variables:

Socket yo = null;            // Socket para comunicarse con el servidor

PrintWriter alServidor;      //  Para poder mandar el string leido al servidor

                                 con el método println()

BufferedReader delTeclado;   // Para leer del teclado con el método readLine()

DataInputStream delServidor; // Para poder leer con readInt() el entero que

                                manda el servidor

String tecleado;             // Almacena el string leido del teclado

Pedir conexión al servidor y crear el socket yo, para la comunicación. comandos es el arreglo de tipo String que requiere el método main, la conexión se pide al puerto 5000.

yo = new Socket(comandos[0],5000);

 

A continuación definimos todos los flujos que necesitaremos. delTeclado es el que me permitirá leer del teclado con el método readLine() que no está desaprobado, System.in es la variable de tipo IntputStream que representa el dispositivo standard de entrada (el teclado). alServidor será el flujo para mandarle al servidor el string leído con el método println(), ademá puedes notar que el constructor, además de un OutputStream requiere un valor booleano, el true indica que el flujo tendré autoflush, que quiere decir que cada vez que se mande un string se mandará inmediatamente y no se almacenará en el buffer intermedio, como normalmente se maneja para hacer más eficiente los flujos, en este caso no queremos eso. Y finalmente delServidor será el flujo que me permita leer del socket un entero mandado por el servidor.

delTeclado  = new BufferedReader(new InputStreamReader(System.in));

alServidor  = new PrintWriter(yo.getOutputStream(),true);

delServidor = new DataInputStream(yo.getInputStream());


En el cliente también necesitamos el ciclo que lea un
string del teclado, se lo mande al servidor y espere el entero que representa la longitud del string mandado. Este ciclo tambié se repetirá hasta que se haya leído un string de longitud 0 o lo que es lo mismo un string nulo.

do{

   System.out.print("Teclea un string: ");

   tecleado = delTeclado.readLine();

   alServidor.println(tecleado);

   System.out.println("Longitud = "+delServidor.readInt());

}while(tecleado.length()!=0);

 

...

Descargar como (para miembros actualizados) txt (25 Kb) pdf (417 Kb) docx (175 Kb)
Leer 29 páginas más »
Disponible sólo en Clubensayos.com