Esta práctica se recogerá, como más tarde, el viernes 4 de abril. La recepción de las prácticas se hará por correo electrónico, por disquete, para lo cual se ruega que confirmen con el profesor la recepción de la práctica (en el caso de correo electrónico). Todo esto sin perjuicio de que el profesor pueda requerir el alumno las explicaciones que considere oportunas sobre el funcionamiento de la solución a la práctica. Las prácticas se entregarán por parejas o individualmente, y son una condición importante para obtener resultados positivos en la convocatoria ordinaria correspondiente. |
Queremos trabajar un poco con procesos, comunicación con sockets, y no desdeñamos en absoluto tratar con temas como servidores multienhebrados, y sincronización entre procesos. El enunciado del problema es muy simple:
Diseñamos e implementamos un sencillo servicio de mensajes. Este servicio es usado por procesos clientes para depositar mensajes en una cola de mensajes (siguiendo cierto protocolo), y para recuperarlos. Los mensajes introducidos en esta cola llevan emparejado un tiempo, que servirá para discernir qué mensajes habrán de ser recuperados por cada cliente según acceda al servidor. Cada cliente, al conectarse recupera todos los mensajes pendientes desde la última conexión.
Este sencillo servicio podría utilizarse como mecanismo de difusión de mensajes en un grupo de clientes (por ejemplo, para jugar al ajedrez entre varios), o como sistema de publicación de novedades en otros servicios nuevos, ya sea un servidor Web, un servidor de noticias, un repositorio ftp, etc... En definitiva, con él podemos extender la funcionalidad de otros servicios. La naturaleza del contenido de los mensajes incluidos en la cola de mensajes es irrelevante para este servidor.
El resto del enunciado de la práctica sigue el siguiente esquema: Requisitos del servidor y aspectos de diseño obligados: tiempo e identificación del cliente y protocolo.
El sistema deberá cumplir los siguientes requisitos:
Cada vez que un Cliente establece una sesión con el servidor éste debe reconocerle como cliente nuevo o como cliente antiguo.
Cuando un cliente nuevo se conecta al servidor establece una identificación que le valida en sucesivas sesiones.
Cuando un cliente nuevo se conecta al servidor recibe de él todos los mensajes de la cola de mensajes.
Cuando un cliente antiguo se conecta al servidor recibe los mensajes nuevos.
Cada cliente puede insertar mensajes en el servidor que constan de una línea de texto.
Cada mensaje lleva asociado un tiempo de generación y ha de ser conservado como tal por el servidor pues puede ser utilizado en las conversaciones entre los clientes y para otros usos.
El envío de mensajes al cliente solo se produce cuando éste envía un mensaje al servidor o cuando lo solicita expresamente.
La noción de tiempo debe ser global entre todos los procesos solo se precisa que pueda establecerse la relación de orden ocurrió_antes( ).
El sistema debe permitir que varios clientes estén activos a la par que haya una sesión establecida con el servidor.
Se entiende que aquellos mensajes que han sido recibidos por todos los clientes registrados del servidor "se consumen", es decir, no son necesarios en lo sucesivo.
Requisitos avanzados, pero no imprescindibles para completar la práctica:
Los mensajes pueden caducar al paso de un tiempo predeterminado por el administrador del servidor. Lógicamente esto conlleva un trabajito extra.
Los clientes también pueden caducar. Aquí hay dos posibilidades:
Un cliente caduca si no hace alguna operación de envío de mensajes.
Un cliente caduca si no se ha conectado durante un tiempo límite.
Un modelo de tiempo que se adapta a lo que necesitamos es el de "Tiempos lógicos" de Lamport, y que aparece descrito en cualquier libro de texto. Según este modelo, cada vez que un proceso recibe un mensaje, aprovecha la ocasión para sincronizar su reloj enviándo un timestamp (marca temporal), si es preciso. Si tanto emisor como receptor intercambian un par de mensajes, podemos sincronizar ambos.
Sería interesante que cada vez que un cliente emitiera un mensaje para el servidor emitiera el tiempo correspondiente para ese mensaje. La razón de ello es que si solo emite tiempo cuando se sincroniza o cuando envía mensajes, si es el caso de que entre medias otro cliente mantiene una sesión con el servidor, perderíamos la ocasión de sincronizar ambos clientes.
La identificación de los clientes se puede hacer de una forma muy sencilla, añadiendo además cierto grado de autenticación mediante una versión descafeinada de lo que es un capability, o habilitación. Al iniciar la sesión, el cliente enviará un mensaje suficientemente largo y aleatorio como para que a cualquiera que desee suplantarlo le sea muy difícil. Obviamente, esto solo es realmente seguro si se produce por un canal seguro (SSL), pero esa sería otra práctica.
En principio se trata de que cualquier cliente que desee conectarse lo pueda hacer, pero no suplantando a otro. Un pequeño problema que presenta este servicio es su vulnerabilidad a un ataque de denegación de servicio, pues, si la cola es grande, además del tráfico, la estructura de datos que mantiene el conjunto de usuarios cliente crecerá.
El protocolo que aquí se propone es muy sencillo, y no se trata coartar la libertad de diseño, sino de estandarizar suficientemente la herramienta para no dispersarse. Dicho protocolo es como sigue:
ts es la marca temporal (timestamp) de cada momento.
CONEXIÓN:
INSERCIÓN DE UN MENSAJE
SINCRONIZACIÓN
DESPEDIDA Y CIERRE
Salvo error o alguna mejora posible, este es el protocolo, a grandes rasgos, y parece suficiente. Hay que tener cuidado con él, pues si no se respeta escrupulosamente, las herramientas no puede interoperar.
Como es muy probable que haya que añadir algún tipo de información adicional para el desenvolvimiento de la práctica, se notificarán los cambios o adiciones en esta página web.
Este enunciado corresponde a una práctica de Sistemas Distribuidos de la Ingeniería Técnica en Informática de Gestión y Sistemas de la Universidad de Valladolid, del curso 2002-2003. Y el derecho de copia y explotación (c) me pertenece a mí (el profesor de la asignatura) y a mis alumnos :-)