# Documentación Tarea nº4

## Programación de Sistemas - ELO 330

Por:
- Luis Fuentes Weber 2503026-5

## Introducción

En esta tarea se requiere programar un chat multiusuario en java, utilizando un modelo cliente – servidor, donde el servidor debe esperar a un número indefinido de clientes, los cuales envían texto anteponiendo su nombre de usuario para identificar a quien envió el texto. El servidor debe recibir el texto y reenviarlo hacia todos los clientes conectados.

Para esto se requiere implementar un cliente que tenga una interfaz gráfica con al menos 3 zonas. En la primera el usuario recibe todos los textos enviados por otros usuarios conectados al servidor, la segunda permite ingresar el texto que un usuario desea enviar al grupo y la tercera zona, corresponde a un botón un botón ("Send") que permite enviar al grupo el texto ingresado.

## Algoritmo y/o Estrategia usada

La estrategia usada en el cliente se puede representar con el siguiente diagrama de clases:

Figura 1: Diagrama de clases del cliente.

Donde la clase ChatClient es la encargada de recoger los argumentos dados por consola, crear el socket y el frame de la aplicación, para luego quedar en un loop esperando datos desde el servidor hasta que la entrada sea nula (termino del buffer de lectura). En caso de recibirse datos, se solicita al panel la actualización de la ventana de texto principal, agregando el string de datos recibido.

La clase clientPane es aquella que crea, inicializa y administra los elementos de la interfaz grafica. Las funciones de administración de la clase son: agregar el texto al final de la ventana principal, obtener el texto de la ventana de input y limpiar esta última, borrando todo su contenido. La interfaz grafica correspondiente a esta clase es:]

Figura 2: Interfaz grafica del cliente.

Por último, la clase sendListener es aquella que implementa el curso a seguir al momento de presionar el botón “Send”, el cual consiste en obtener y eliminar el texto de input desde el panel, y a través de una hebra (para no detener el funcionamiento del programa al enviar textos largos) invocar el método sendData. Éste último divide el string en líneas separadas por un retorno, y envía cada una de ellas por separado anteponiendo el nombre de usuario, y así evitar la personificación, asegurándose de que al comienzo de cada línea lo primero que siempre sea el nombre de usuario. Para evitar que 2 textos largos enviados consecutivamente sean enviados de forma desordenada o intercalada, este método se sincronizo con una variable única arbitraria, escogiendo en este caso el nombre del usuario, tal que se terminara de enviar el texto de una hebra para empezar a enviar en la otra.

Por otro lado, el diagrama de clases del servidor es:

Figura 3: Diagrama de clases del servidor.

El que de forma similar que al cliente, tiene una clase principal, ChatServer, la que se encarga de recibir los argumentos y crear el socket de escucha, el vector de clientes y el frame para la interfaz grafica, para luego quedar en un loop infinito esperando por nuevas conexiones. Al aceptar una conexión se agrega el nuevo cliente al vector y se crea una hebra (serverThread), pasándole los datos del nuevo cliente y la referencia al vector de clientes, para luego volver a esperar por nuevas conexiones.

La clase serverThread implementa una hebra que se encarga de manejar la conexión de un cliente en específico. Esta, al ejecutarse, queda inmediatamente esperando por datos desde su respectivo cliente hasta recibir un string nulo, el que indica el fin del buffer de lectura. Al recibir un dato, se invoca al método send con el string recibido, el que reenvía el string a todos los clientes incluidos en el vector utilizando el candado de este para sincronizar el envío, talque todos los clientes recibían los datos en el mismo orden. En el caso de que se cierre un cliente u ocurra una falla en la conexión, se elimina de forma sincronizada el cliente del vector, para evitar que se elimine mientras otra hebra está enviando datos, y la hebra termina.

El panel creado, mediante la clase serverPane, consiste en una única ventana de texto que indica la cantidad de clientes conectados, la dirección ip o hostname de los clientes y el puerto local al cual cada uno esta comunicado. Cada vez que se conecta o desconecta un cliente, el panel se reescribe con los clientes presentes en el vector. La interfaz grafica del servidor, con 2 clientes conectados en desde localhost es la siguiente:

Figura 4: Diagrama de clases del cliente

Finalmente se opto por usar una clase extra, clientData, la que además de guardar el socket del cliente, en su constructor crea un print writer, el que es usado para enviar los datos al socket respectivo y así evitar el overhead que significa tener que crearlo para cada cliente, cada vez que se desea enviar un string.

Cabe destacar que, tanto en el cliente como en el servidor, todas las excepciones son desplegadas gráficamente en un dialogo indicando el error.

##

## Ejecución y compilación del programa

## El código fuente está dividido en 2 directorios, para el cliente y el servidor respectivamente. Además se creó un makefile, el que al ejecutar make en consola, compila automáticamente los bytecodes de las clases necesarias, los que quedaran almacenados dentro de su respectivo directorio. Ubicándose en el directorio correspondiente, la sintaxis para la ejecución de los programas es:

## Cliente:

## java ChatClient [User_name] [Host_server] [Port]

## Donde:

## - [User_name]: Puerto en el que el cliente quedará escuchando por trafico UDP.

## - [Host_server]: Nombre o dirección IP del servidor del chat.

## - [Port]: Puerto de escucha del servidor del char.

## Servidor:

## java ChatServer [Port]

## Donde:

## - [Port]: Puerto en el que el servidor quedara esperando por solicitudes de conexiones desde clientes del chat.

## Adamas, para generar la documentación en javadoc, escribiendo “make doc” en consola, se crearan 2 nuevos directorios, client_doc y server_doc, los que contienen los archivos correspondientes al cliente y el servidor respectivamente. Cabe destacar que es posible compilar los bytecodes y los archivos de documentación del cliente o servidor por separado, con “make client” y “make client_doc” se generaran los del cliente y con “make server” y “make server_doc” los del servidor.

## Conclusiones

## Se estudio y manipulo exitosamente el establecimiento de conexión por sockets, el uso de hebras y sincronización de variables en java, e integrarlos mediante una interfaz grafica. Finalmente se logro crear el programa, cumpliendo los requisitos pedidos, además de agregar otras funcionalidades como el despliegue mediante una interfaz grafica de los clientes conectados al servidor.