File - PROGRAMACION CONCURRENTE Y PARALELA

Anuncio
Arquitectura de Servidores




Servidores Concurrentes
Servidores Iterativos
Servidores con Estado
Servidores sin Estado
Qué pasa cuando varios clientes tratan de conectarse
al mismo tiempo a un servidor

Una forma es ir atendiéndolos de a uno en un ciclo: como en el
programa que atiende pedidos de archivos







Se acepta una conexión
Se lee la petición
Se lee desde el archivo y se escribe en el socket hasta encontrar una
marca de fin de archivo
A este tipo de servidores se les llama servidores iterativos
El problema es que todo cliente tiene que esperar su turno para
ser atendido
Si uno de ellos pide un archivo muy grande los demás tienen que
esperar
La mayor parte de la espera es debido a operaciones de IO,
hay capacidad de CPU ociosa !
Un servidor secuencial (iterativo)
atendiendo a más de un cliente
A CLIENT
A SERVER
A CLIENT
4444
A CLIENT
Durante la conversación no puede
oír por el puerto 4444
A CLIENT
A SERVER
A CLIENT
4444
A CLIENT
Si el servicio consiste en transferir
un archivo, el cliente debe digitar el
nombre
A CLIENT
A SERVER
A CLIENT
4444
A CLIENT
Sólo después de efectuar la
transmisión se pone a escuchar de
nuevo por el 4444
A CLIENT
A SERVER
A CLIENT
4444
A CLIENT
¿Qué sucede si el servidor tiene que
esperar mucho para que un cliente
escriba el nombre de un archivo?
A CLIENT
A SERVER
Timeout
A CLIENT
4444
A CLIENT
ArchServidor2
Un Servidor Concurrente






Un servidor concurrente atiende a varios clientes al
mismo tiempo.
Más aún, mientras está atendiendo sigue escuchando
El problema es que todo cliente tiene que esperar su
turno para ser atendido.
Si uno de ellos pide un archivo muy grande los demás
tienen que esperar
La mayor parte de la espera es debido a
operaciones de IO, hay capacidad de CPU ociosa!
Se trata de crear un nuevo proceso o línea de
ejecución cada vez que un cliente “llega” a pedir un
servicio.
Servidores Comcurrentes: hay procesos
separados para atender el puerto y para
transferir el archivo
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Después que el cliente contacta al servidor,
éste crea otro proceso para para atender al
cliente y se queda escuchando el puerto 4444
por otro
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Mientras el nuevo proceso está atendiendo al
primer cliente, el segundo cliente puede
contactar al servidor en el puerto 4444
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Y el servidor crea otro proceso
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Ahora un tercer cliente contacta al
servidor
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Y un tercer proceso esclavo o
thread es creado
A CLIENT
A SERVER
4444
A CLIENT
A CLIENT
Algoritmo de Servidor Concurrente
Programa principal o “master” del servidor
1. Crear un Socket de servidor
En un ciclo infinito:
2. Aceptar requerimientos de clientes
3. Cuando llega una petición de un cliente crear un nuevo
proceso “esclavo” que atienda paralelamente la petición
(esto no debe bloquear la ejecución del programa master del
servidor)
4. Volver a 2.
Proceso esclavo:
1. Recibir los parámetros de la comunicación (socket o flujos de
entrada y/o salida)
2. Atender al cliente (ej: leer el nombre del archivo, transmitir el
archivo)
3. Retornar (desaparecer !)
Proceso que crea un hilo para cada
Cliente Conectado
public class MiHilo extends Thread
{
BufferedReader flujoL;
PrintWriter flujoE;
public MiHilo(Socket s)
{
// obtención de los flujos de L/E
}
public void run()
{
// resolución del problema
// manejando los flujos de L/E
}
}
public class Servidor
{
public static void main(String args[])
{
ServerSocket serv;
serv = new ServerSocket(9999);
while(true)
{
Socket s = serv.accept();
MiHilo hilo = new MiHilo(s);
hilo.start();
}
}
}
Proceso que crea un hilo para la lectura y un hilo
para la escritura a través de un socket
public class MiHiloL extends Thread
{
BufferedReader flujoL;
public MiHilo(Socket s)
{
// obtención del flujo de L
}
public void run()
{
// resolución del problema
// manejando el flujo de L
}
}
public class MiHiloE extends Thread
{
PrintWriter flujoE;
public MiHilo(Socket s)
{
// obtención del flujo de E
}
public void run()
{
// resolución del problema
// manejando el flujo de E
}
}
public class Proceso
{
public static void main(String args[])
{
Socket s = new Socket(“localhost”,
9999)
MiHiloL hiloL = new MiHiloL(s);
MiHiloE hiloE = new MiHiloE(s);
hiloL.start();
hiloE.start();
}
}
}
Ejercicio 1:

Servidor: Acepta conexiones en el puerto 9999. Recibe una cadena del cliente y la convierte
a mayúsculas. Creará un hilo para cada cliente conectado.

Cliente: Envía una cadena al servidor y muestra en pantalla la respuesta del servidor.
Ejercicio 2: Implementar un “teléfono”
Servidor:

Acepta 2 clientes conectados en el puerto 8888.

Crea dos hilos para manejar lo que cada cliente envía.

Cada hilo leerá la información de un socket “origen” y lo enviará por un socket “destino”.

Finalizan cuando los dos clientes envíen la palabra “FIN”.
Cliente:

Creará un hilo para la lectura de frases del teclado y envío a través del socket. Finalizará
cuando se introduzca “FIN”.

Creará un hilo para mostrar por pantalla la información que lea del socket. Finalizará cuando
reciba “FIN”.
Descargar