mi taller de sockets e hilos en java

15
Actividad Aplicativa Colaborativa: Unidad 1 Mi taller de sockets e hilos en Java Titulación: Grado en Ingeniería Informática Asignatura: Programación Concurrente y de Tiempo Real

Upload: carlosmb83

Post on 20-Jan-2016

117 views

Category:

Documents


4 download

DESCRIPTION

Mi taller de sockets e hilos en Java

TRANSCRIPT

Page 1: Mi Taller de Sockets e Hilos en Java

Actividad Aplicativa Colaborativa: Unidad 1

Mi taller de sockets e hilos en Java

Titulación: Grado en Ingeniería Informática

Asignatura: Programación Concurrente y de Tiempo Real

Madrid, Febrero de 2012

Page 2: Mi Taller de Sockets e Hilos en Java

Tabla de Contenidos

1 OBJETIVOS..........................................................................................................................................................3

2 ENUNCIADO.................................................................................................................................... 3

3 DESARROLLO DE LA PRÁCTICA...............................................................................................33.1 ¿QUE OCURRE CUANDO VARIOS CLIENTES, AL MISMO TIEMPO, INTENTAN CONTACTAR CON EL SERVIDOR DE TIEMPO?............................................................................................................................................33.2 SOLUCIONE EL PROBLEMA DEL PUNTO 3.1 Y OBTENGA UN CÓDIGO EN JAVA PARA QUE EL SERVIDOR GESTIONE PETICIONES DE CLIENTE SIMULTÁNEAS. COMENTE LA SOLUCIÓN PROPUESTA.......43.3 REALICE UN PROGRAMA QUE PIDA AL USUARIO UNA RUTA Y UNA LISTA DE DIRECCIONES WEB Y LUEGO DESCARGUE EL TEXTO CONTENIDO EN CADA UNA DE LAS DIRECCIONES WEB EN UN FICHERO DISTINTO (DENTRO DE LA RUTA). LA DESCARGA DE TODAS LAS PA GINAS WEB DEBE REALIZARSE EN PARALELO..................................................................................................................................................................6

4 ANEXO: CÓDIGO FUENTE........................................................................................................... 64.1 CÓDIGO FUENTE APARTADO 3.1...............................................................................................................7

4.1.1 ClienteHora.java................................................................................................................................. 74.1.2 ServidorHora.java.............................................................................................................................. 7

4.2 CÓDIGO FUENTE APARTADO 3.2...............................................................................................................94.2.1 ClienteHora.java................................................................................................................................. 94.2.2 ServidorHora.java........................................................................................................................... 104.2.3 HiloCliente.java................................................................................................................................ 11

4.3 CÓDIGO FUENTE APARTADO 3.3............................................................................................................114.3.1 DescargaTextoWeb.java...........................................................................................................11

2

Page 3: Mi Taller de Sockets e Hilos en Java

1 Objetivos

- Interpretar el funcionamiento de los sockets e hilos en Java.- Aplicar los conocimientos adquiridos a través de la elaboración de un

programa.- Probar el correcto funcionamiento del programa.

2 Enunciado

Se proponen varias cuestiones y ejercicios practicos que los estudiantes deberan resolver, entregando una pequena memoria donde vendran resueltos y comentados.

Solo existen dos calificaciones posibles: Apto si se ha entregado esta memoria y se han realizado de forma correcta los ejercicios y cuestiones y No Entregado si no se han entregado. Si se entregan pero existen errores, el alumno sera instado a repetir la memoria hasta que esté correcta.

1) ¿Qué ocurre cuando varios clientes, al mismo tiempo, intentan contactar con el servidor de tiempo?

2) Solucione el problema visto en el punto 1, obteniendo un código en Java para el servidor y comente la solución propuesta (en la memoria hay que adjuntar el código como parte de la solución).

3) Realice un programa que pida al usuario una lista de direcciones web y luego descargue el texto contenido en cada una de las direcciones web en un fichero distinto (la ruta dónde han de ir los ficheros también hay que pedirsela al usuario). La descarga de todas las paginas web debe realizarse en paralelo.

a. Como ayuda para la realizacion de este ejercicio, vease el Javadoc de la clase URL, que ofrece un metodo capaz de devolver un InputStream asociado a la conexion con la URL.

3 Desarrollo de la práctica

3.1 ¿Que ocurre cuando varios clientes, al mismo tiempo, intentan contactar con el servidor de tiempo?

En este apartado se ha utilizado el código ClienteHora.java (ver anexo 4.1.1) y ServidorHora.java (ver anexo 4.1.2) para demostrar que ocurre cuando varios clientes intentan contactar de manera simultanea con el servidor .

- ClienteHora: implementa la recepción de información mediante socket al invocar el método getInputStream().

- ServidorHora.java: o Implementa un servidor que acepta conexiones mediante la clase

ServerSocket y el método accept()

3

Page 4: Mi Taller de Sockets e Hilos en Java

o Ademas, realiza el envio de información mediante socket al invocar al método getOutputStream().

Para comprobar que ocurre cuando varios clientes son ejecutados al mismo tiempo hemos realizado la siguiente ejecución:

1) Ejecutar ServidorHora.java2) Ejecutar ClienteHora.java

Al realizar la ejecución, hemos comprobado como la llamada servidor.accept() sólo permite aceptar conexiones de un cliente y después de haberlas gestionado es capaz de aceptar conexiones de otro cliente. Pero, de manera secuencial, no de manera concurrente.

3.2 Solucione el problema del punto 3.1 y obtenga un código en Java para que el servidor gestione peticiones de cliente simultáneas. Comente la solución propuesta.

El objetivo de este apartado es realizar un servidor de socket que pueda atender a varios clientes a la vez. Para ello, vamos a dar al ServidorHora la funcionalidad necesaria para que pueda crear un hilo por cada uno de los clientes que tiene que atender. A continuación explicamos la solución que hemos implementado.

Clase ClienteHoraLa clase ClienteHora se ha mantenido como estaba en el apartado anterior ya que

para implementar una solución que permita peticiones simultaneas, es el servidor, el que debe atender dichas peticiones. Por tanto, la programación de los clientes seguira siendo la misma y los clientes estaran solicitando la hora al servidor.

ClienteHora - Fragmento de código representativo: (ver código en anexo 4.2.1)

Clase ServidorHora y Clase HiloClienteEn la clase ServidorHora hemos tenido que realizar una importante modificación.

Como comentabamos al principio de este apartado, para poder permitir peticiones de manera concurrente, necesitamos crear un hilo por cada una de estas peticiones. De esta manera, ninguna tiene que esperar para ser atendida. Para llevarlo a cabo, hemos creado la clase HiloCliente que implementa la interfaz runnable y permite la creación de hilos.

Desde la clase ServidorHora seguiremos creando un servidor que atienda peticiones, pero en vez de atender las peticiones desde el servidor, crearemos hilos de la clase HiloCliente para que sea dentro del hilo donde se envie el cliente la información

4

Page 5: Mi Taller de Sockets e Hilos en Java

solicitada. En nuestro caso, se le enviara al cliente la hora actual. A continuación incluimos los fragmentos de código mas representativos de ambas clases:

ServidorHora - Fragmento de código representativo: (ver código en anexo 4.2.2)

HiloCliente - Fragmento de código representativo: (ver código en anexo 4.2.3)

TEST1: Prueba de la concurrencia de clientesPara comprobar que se ha realizado correctamente lo concurrencia de peticiones,

se van a mostrar las salidas que nos ha dado el programa por consola. En estas salidas se puede comprobar el PID inicial del servidor y el PID de los

hilos que se han creado conforme hemos ejecutado peticiones de cliente.

Paso 1: Inicializamos ServidorHora:

Paso 2: Lanzamos varias peticiones simultaneas ClienteHora y el servidor crea tantos hilos como necesita:

5

Page 6: Mi Taller de Sockets e Hilos en Java

Paso 3: Cliente recibe la respuesta del hilo (Mostramos la salida de una de las ejecuciones de la clase ClienteHora)

TEST2: Prueba de la concurrencia de clientesDespués de realizar el TEST1 que consistia en ir pulsando “Run” desde eclipse

para ir ejecutando varios clientes simultaneos, hemos planteado implementar un bucle for de 5 iteraciones en el cliente para que la concurrencia fuera mas visual. Este es el resultado:

Salida ServidorHora:

Salida ClienteHora:

3.3 Realice un programa que pida al usuario una ruta y una lista de direcciones web y luego descargue el texto contenido en cada una de las direcciones web en un fichero distinto (Dentro de la ruta). La descarga de todas las páginas web debe realizarse en paralelo.

Explicar la solución propuesta e incluir el código en el anexo

4 Anexo: Código Fuente

6

Page 7: Mi Taller de Sockets e Hilos en Java

4.1 Código fuente apartado 3.1

4.1.1 ClienteHora.java/* * ClienteHora.java * Autores: Carlos Morales Becerra y Andres vargas Beato */

package cliente;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException;

import servidor.ServidorHora;

public class ClienteHora {

public static void main(String[] args) {Socket s;try {

System.out.println("Cliente solicita hora");//Creamos un nuevo socket para conectarnos al servidors = new Socket("127.0.0.1", ServidorHora.puerto);//Creamos una variable InputStream donde recibiremos la

información del servidorInputStream entrada = s.getInputStream();//A partir del inputstream creamos un buffer de lectura que

almacenara la información recibidaBufferedReader lector = new BufferedReader (new

InputStreamReader(entrada));//Mostramos por pantalla el contenido del buffer, en nuestro caso

la hora.System.out.println(lector.readLine());//Cerramos el sockets.close();

} catch (UnknownHostException e) {e.printStackTrace();

} catch (IOException e) {e.printStackTrace();

}}

}

4.1.2 ServidorHora.javapackage servidor;import java.io.IOException;

7

Page 8: Mi Taller de Sockets e Hilos en Java

import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.text.DateFormat;import java.util.Date;import java.util.GregorianCalendar;

public class ServidorHora {

public static final int puerto = 9797;

private static String darHora(){GregorianCalendar calendario = new GregorianCalendar();Date date = calendario.getTime();DateFormat hora = DateFormat.getTimeInstance(DateFormat.SHORT);return hora.format(date);

}/** * @param args */public static void main(String[] args) {

ServerSocket servidor;try {

//Creamos un servidor de socket para atender peticionesservidor = new ServerSocket (puerto);System.out.println("Servidor esperando...");while (true){

//Esperamos a recibir y aceptar alguna peticiónSocket aux = servidor.accept();/*A partir del método getOutputStream creamos un PrintWriter que nos servira para enviar

información*/PrintWriter escritor = new

PrintWriter(aux.getOutputStream());//Enviamos la información de la hora actualescritor.println(darHora());//Cerramos el printWriterescritor.close();//Cerramos el socketaux.close();

}} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

}

}

}

8

Page 9: Mi Taller de Sockets e Hilos en Java

4.2 Código fuente apartado 3.2

4.2.1 ClienteHora.javapackage cliente;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.Socket;import java.net.UnknownHostException;

import servidor.ServidorHora;

public class ClienteHora {

/** * @param args */public static void main(String[] args) {

Socket s;try {

for (int i = 0; i<5;i++){System.out.println("Cliente solicita hora");//Creamos un nuevo socket para conectarnos al servidors = new Socket("127.0.0.1", ServidorHora.puerto);//Creamos una variable InputStream donde recibiremos la

información del servidorInputStream entrada = s.getInputStream();System.out.println("Cliente lee la hora enviada por el servidor");//A partir del inputstream creamos un buffer de lectura que

almacenara la información recibidaBufferedReader lector = new BufferedReader (new

InputStreamReader(entrada));//Mostramos por pantalla el contenido del buffer, en nuestro caso

la hora.System.out.println("Son las: "+lector.readLine());//Cerramos el sockets.close();}

} catch (UnknownHostException e) {e.printStackTrace();

} catch (IOException e) {e.printStackTrace();

}}

}

9

Page 10: Mi Taller de Sockets e Hilos en Java

4.2.2 ServidorHora.javapackage servidor;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.text.DateFormat;import java.util.Date;import java.util.GregorianCalendar;

public class ServidorHora {

public static final int puerto = 9797;

public static String darHora(){GregorianCalendar calendario = new GregorianCalendar();Date date = calendario.getTime();DateFormat hora =

DateFormat.getTimeInstance(DateFormat.MEDIUM);return hora.format(date);

}/** * @param args */public static void main(String[] args) {

System.out.println("PID Servidor: "+String.valueOf(Thread.currentThread().getId()));

ServerSocket servidor;try {

//Creamos un servidor de socket para atender peticionesservidor = new ServerSocket (puerto);System.out.println("Iniciamos servidor");while (true){

//Esperamos a recibir y aceptar alguna peticiónSystem.out.println("Servidor esperando conexiones");Socket aux = servidor.accept();System.out.println("Servidor recibe conexión y crea nuevo

hilo");Thread hilo = new Thread(new HiloCliente(aux));hilo.start();

}} catch (IOException e) {

// TODO Auto-generated catch blocke.printStackTrace();

}

}

}

10

Page 11: Mi Taller de Sockets e Hilos en Java

4.2.3 HiloCliente.javapackage servidor;

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

public class HiloCliente implements Runnable{

Socket socket;

public HiloCliente(Socket socket){this.socket = socket;

}

@Overridepublic void run() {

PrintWriter escritor;try {

System.out.println("PID HiloCliente: "+String.valueOf(Thread.currentThread().getId()));

/*A partir del método getOutputStream creamos un PrintWriter que nos servira para enviar información*/escritor = new PrintWriter(socket.getOutputStream());//Enviamos la información de la hora actualescritor.println(ServidorHora.darHora());//Cerramos el printWriterescritor.close();

} catch (IOException e) {e.printStackTrace();

}

}

}

4.3 Código fuente apartado 3.3

4.3.1 DescargaTextoWeb.javaIncluir código

11