Está en la página 1de 10

Laboratorio de Fundamentos de Sistemas Distribuidos

Chat en Java - 1
Tipo de entrega: por grupos de prcticas
Fecha lmite: sesiones de laboratorio
Lugar: Atenea (nou campus)
Objetivos del proyecto:
Crear y utilizar objetos
Crear y utilizar variables y mtodos de clases
Utilizar try, catch y finally para detectar y manejar excepciones
Implementar clientes y servidores en Java que se comuniquen entre s utilizando
sockets
Implementar un servidor con subprocesamiento mltiple
Resultados a entregar:
Los resultados esperados de esta prctica es la carpeta del Workspace del Eclipse
que contiene los cdigos de las aplicaciones. Coloca los cdigos de cada sesin en un
package llamado Chat_X

Descripcin de la aplicacin
En este proyecto vamos a desarrollar una aplicacin distribuida con arquitectura
cliente/servidor. La aplicacin distribuida es un Chat que permite a los clientes darse de alta y
de baja en el Chat, enviar mensajes a todos los clientes en lnea y pedir la lista de clientes en
lnea.

El cdigo del cliente se programar en la clase ClienteChat (ClienteChat.java) y el


cdigo del servidor en las clases ServidorChat (ServidorChat.java) y Cliente
(Cliente.java)

Estudio Previo
1. Estudio de los apartados (Sockets, Clients, and Servers, y Programming
Examples) de la seccin 10.4 (Networking) del libro Introduction to Programming
Using Java Version 4.0, July 2002 de David J. Eck (en el apartado comentarios
tienes cmo acceder on-line al contenido del libro)

2. Compila, ejecuta y analiza detenidamente el ejemplo DateServer.java y


DateClient.java. Esta aplicacin utiliza un objeto de la clase PrintWriter para escribir
datos en un socket y un objeto de la clase Reader para leer datos de un socket.

Nota:
Para compilar DateServer.java y DateClient.java necesitas la clase TextIO.class que
es una clase que no pertenece al SDK.
Coloca el cdigo fuente de TextIO.java en el mismo package que el cdigo
DateServer.java y DateClient.java para que puedas usar la clase TextIO.
La clase TextIO slo se usa como clase de soporte (no es necesario que la entiendas
para realizar la prctica)

3. Prueba a NO arrancar el servidor de la aplicacin DateServer.java y DateClient.java y


arranca el cliente. Analiza la secuencia de sentencias que se ejecutan cuando
ejecutas el cliente (trelo a la sesin de laboratorio en papel)

4. Compila, ejecuta y analiza detenidamente el ejemplo CLChatClient.java y


CLChatServer.java. Esta aplicacin utiliza un objeto de la clase PrintWriter para

1
escribir datos en un socket y un objeto de la clase TextReader para leer datos de un
socket.

Nota:
Para compilar estos ejemplos sucede lo mismo que en los ejemplos del apartado
anterior (aqu necesitas la clase TextReader.class)
Coloca el cdigo fuente de TextReader.java en el mismo package que el cdigo de
CLChatClient.java y CLChatServer.java para que puedas compilar los ejemplos.
En el apartado comentarios tienes donde hay una explicacin de esta clase y de sus
mtodos.

5. Prueba a arrancar el servidor de la aplicacin CLChatClient.java y CLChatServer.java


y NO arranques el cliente de la aplicacin. Analiza la secuencia de sentencias que se
ejecutan en el servidor (trelo a la sesin de laboratorio en papel)

6. Analiza el protocolo que utiliza el servidor de nuestro chat formado por las clases
ServidorChat.java y Cliente.java. Si programamos el cliente en una clase
ClienteChat.java, Qu deber enviar ClienteChat por el socket para registrarse?
(trelo a la sesin de laboratorio en papel)

Comentarios
Introduction to Programming Using Java Version 4.0, July 2002
El libro Introduction to Programming Using Java Version 4.0, July 2002 de David J. Eck
(eck@hws.edu) est accessible on-line desde http://www.faqs.org/docs/javap/index.html

El cdigo fuente de las aplicaciones lo puedes bajar de


http://www.faqs.org/docs/javap/source/index.html

Tambin puedes bajarte el manual y los ejemplos en un archivo comprimido para Windows,
Linux/UNIX and MacOS X y Linux/UNIX ( apartado Downloading Links ) o slo el manual
en un archivo pdf.

Clase TextReader
Se describe la clase y cmo usarla en la seccin 10.1 (Streams, Readers, and Writers) del
manual Introduction to Programming Using Java Version 4.0, July 2002.

Cmo debugar en el Eclipse


Tienes un ejemplo grfico de cmo hacerlo en la ayuda del Eclipse (abre el Help del Eclipse y
busca el tema Debugging your programs)

Streams, Readers and Writers


Puedes consultar informacin de estas clases en las secciones 10.1 (Streams, Readers, and
Writers), 10.2 (Files) y 10.3 (Programming with Files) del manual Introduction to
Programming Using Java Version 4.0, July 2002.

Sockets

En Java la programacin de aplicaciones que se comunican en


Internet a travs del protocolo TCP (Transmisin Control
Protocol) se realiza desde la capa de aplicacin, sin necesidad de
interactuar con la capa de transporte. Para ello se utilizan las
clases Socket y ServerSocket, que proporcionan
comunicacin en red independiente de la plataforma.

2
Un socket es un punto final de una comunicacin bidireccional entre 2 programas
ejecutndose en la red. Un socket se asocia a un nmero de puerto de forma que el
protocolo de la capa de transporte (en nuestro caso TCP) pueda identificar la aplicacin a la
que estn destinados los datos. As, los sockets permiten crear la ilusin al programador de
que mandar/recibir datos por la red es algo similar a escribir/leer datos de un disco.

El servidor corre sobre una mquina y tiene un socket asociado a un puerto determinado, por
el que est esperando la peticin de una conexin de un cliente.

El cliente conoce el nombre de la mquina donde se est ejecutando el servidor y el nmero


de puerto por el que est escuchando el servidor.

El cliente realiza una peticin de


conexin al servidor con el nombre de
mquina del servidor y el puerto.

Si no se produce ningn error el


servidor acepta la conexin. Crea un
nuevo socket para atender la peticin
de ese cliente y mantiene el socket
original que est escuchando para
atender peticiones de nuevos clientes.

A partir de este momento el cliente y el servidor pueden comunicarse leyendo o escribiendo


en sus sockets.

La clase Socket implementa un lado de la conexin bidireccional entre dos aplicaciones Java
en la red. Permite crear conexiones de clientes con servidores. La clase ServerSocket
implementa el otro lado de la conexin bidireccional. En concreto permite crear un socket que
puede escuchar en un puerto y aceptar conexiones de clientes.

Ambas son implementaciones que ocultan los detalles de las plataformas concretas (hardware
y sistema operativo) donde se ejecutan las aplicaciones cliente y servidor.

Sesin de laboratorio
Ejercicio 1: sockets

Escribe un programa cliente llamado ClienteChat.java que se conecte y desconecte del


servidor formado por las clases ServidorChat.java y Cliente.java que te damos.

El cliente debe realizar esta secuencia:


1. pedir el nick al usuario del Chat
2. registrarse en el servidor (enviando el comando REGISTER y el nick)
3. pedir al usuario un comando y ejecutar el comando
4. Si el comando es CLOSE finalizar la aplicacin. En caso contrario volver a 3.-

De momento los comandos que soporta nuestra aplicacin son conectarse al servidor y
desconectarse. Si el usuario introduce cualquier otro comando distinto se printar un mensaje
por pantalla informativo en la consola de ClienteChat y se pedir al usuario que introduzca un
nuevo comando.

Utiliza a clase BufferedReader para leer de un socket. Utiliza la clase PrintWriter para escribir
en un socket. Utiliza la clase JOptionPane para introducir el nick del usuario y para leer los
comandos que introduce el usuario.

3
Chat en Java - 2
Estudio Previo
1. Estudio de los apartados (ArrrayLists , y Vectors) de la seccin 8.3 (Dynamic
Arrays, ArrayLists, and Vectors) del libro Introduction to Programming Using Java
Version 4.0, July 2002 de David J. Eck (en el apartado comentarios tienes cmo
acceder on-line al contenido del libro)
2. Estudio del apartado (The Special Variables this and super) de la seccin 5.5 (this
and super) del libro Introduction to Programming Using Java Version 4.0, July
2002 de David J. Eck (en el apartado comentarios tienes cmo acceder on-line al
contenido del libro)
3. Programa una clase llamada MyClass (en un archivo MyClass.java) que tenga un
mtodo llamado myMethod. El mtodo myMethod imprime por pantalla el mensaje
Soy un mtodo de la clase MyElement.
Programa una clase llamada CheckAL (en un archivo CheckAL.java) que almacene en
un objeto de la clase ArrayList objetos de la clase MyClass, recorra el ArrayList y
ejecute para cada elemento el mtodo myMethod programado en la clase MyClass.
(trelo a la sesin de laboratorio en papel)

Comentarios
Introduction to Programming Using Java Version 4.0, July 2002
El libro Introduction to Programming Using Java Version 4.0, July 2002 de David J. Eck
(eck@hws.edu) est accessible on-line desde http://www.faqs.org/docs/javap/index.html

El cdigo fuente de las aplicaciones lo puedes bajar de


http://www.faqs.org/docs/javap/source/index.html

Tambin puedes bajarte el manual y los ejemplos en un archivo comprimido para Windows,
Linux/UNIX and MacOS X y Linux/UNIX (apartado Downloading Links ) o slo el manual
en un archivo pdf.

La clase Vector

La clase Vector permite almacenar un array dinmico de objetos e ir aadiendo objetos o


eliminndolos, as como llamar a otros mtodos que se necesitan cuando trabajas con
cualquier conjunto de objetos

Analiza este fragmento de cdigo que crea un Vector de objetos, aade un objeto de la clase
Client al Vector y llama al atributo name de cada objeto Client que hay en el vector, sin
necesidad de conocer cuantos clientes hay en el vector (mtodo size() de la clase Vector):
import java.util.* ;
Vector clients = new Vector();
Client cl =new Client();
clients.addElement(cl);
for (int i=0; i<clients.size();i++){
((Client)(clients.elementAt(i))).name;
}
clients.removeElement(cl);
clients.toString();

Es importante hacer notar varios aspectos en el cdigo:

4
La sentencia import java.util.*; permite utilizar todo lo que contiene el package
java.util de Java y la clase Vector se encuentra en ese package(similar al include de
C)

El mtodo addElement() introduce un elemento en el Vector

El mtodo removeElement() elimina un elemento del Vector

El mtodo size() de la clase Vector permite conocer el nmero de objetos que


contiene el objeto Vector sobre el que se aplica (clients).

El mtodo element.At(i) devuelve una referencia que apunta al objeto que hay en la
posicin i del objeto Vector sobre el que se aplica (en nuestro caso apunta un objeto
Client).

Como los elementos de un Vector pertenecen por defecto a la clase padre ms


genrica (Object) para acceder al atributo name de la clase Cliente hay que forzar la
conversin del tipo (como en C)

((Client)(clients.elementAt(i))).name;

Sesin de laboratorio
Ejercicio 2: La clase Vector

En este ejercicio vamos a aadir a nuestro servidor la funcionalidad de almacenar la


informacin de los clientes que estn conectados en el servidor y vamos a aadir a nuestra
aplicacin un nuevo comando (comando SEND_CLIENT_LIST) que permite a un usuario del
chat saber los nicks de los usuarios registrados en el servidor.

Vector clientList

Cada vez que un usuario se conecta (comando REGISTER), se aade un objeto de la


clase Cliente en el Vector clientList.

Cada vez que un usuario se desconecta (comando CLOSE), se elimina el objeto que
representa a ese usuario del Vector clientList.

Comando SEND_CLIENT_LIST

El comando lo declaramos como una constante llamada SEND_CLIENT_LIST de tipo char


que contiene el carcter :

El cliente enva SEND_CLIENT_LIST (:) al servidor y recibe una lnea por cada usuario
registrado en el servidor < + el atributo name de ese cliente ms una lnea
con > que indica fin de comando SEND_CLIENT_LIST (:). Por ejemplo, si el servidor
tuviera dos clientes registrados Pablo y Toi, se recibira:
>Pablo
>Toi
<

Los caracteres > y < los declaramos como constantes de tipo char llamadas
CLIENT_INFO y END_CLIENT_INFO .

5
a) Modifica el cdigo de nuestra aplicacin aadiendo el Vector clientList en la parte de
servidor (se declara e inicializa en ServidorChat y se pasa por parmetro cuando se crea un
objeto Cliente), actualizando el Vector clientList cada vez que un usuario se conecte
(comando REGISTER) o se desconecte (comando CLOSE) y programando el nuevo
comando en nuestro Chat (tanto en la parte de cliente como en la parte de servidor)

En la parte de ClienteChat crea un nuevo Vector cada vez que se pida un


SEND_CLIENT_LIST al servidor y almacena en l los nicks de los usuarios que vas
recibiendo. Cuando recibas fin del comando SEND_CLIENT_LIST (<) printa por pantalla la
lista de usuarios que tienes en el vector

Como nuestro Chat slo atiende a un ClienteChat (es secuencial), slo permite un ClienteChat
conectado al Chat no podemos probar que SEND_CLIENT_LIST devuelva ms de un name.

Nota: Existen varias formas de compartir la lista de usuarios. Una es utilizando el comando
static y otra es pasando una referencia del objeto clientList. Cualquiera de las dos formas
es valida.

Chat en Java - 3
Estudio Previo
1. Estudio del tutorial Threads (Scheme) de javaHispano.
2. Programa una clase llamada MyThread (en un archivo MyThread.java) que sume
enteros de 1 a 10.000 y una clase llamada Prueba (en un archivo Prueba.java) que
cree un thread y lo ponga en marcha (trelo a la sesin de laboratorio en papel)

Comentarios
javaHispano
El web javaHispano (http://www.javahispano.org) mantiene noticias, manuales, tutoriales de
Java en castellano.

El manual de esta parte de la prctica se encuentra en la seccin Java / Tutoriales / J2SE


(http://www.javahispano.org/tutorials.type.action?type=j2se) bajo el nombre Threads
(Scheme)

Threads

Los threads o hilos de ejecucin son segmentos de cdigo de un programa que se ejecutan
secuencialmente de modo independiente de otras partes del programa. Un proceso puede
estar constituido por uno o ms threads. Un
thread esta compuesto por: una CPU virtual, el
cdigo que ejecuta el procesador y los datos
sobre los que trabaja el cdigo. Dos threads
comparten cdigo si ejecutan cdigo de objetos
que pertenecen a la misma clase

Los datos pueden ser o no compartidos por


diferentes threads. Eso ocurre cuando tienen
acceso a un objeto comn.

6
Los threads se utilizan para aislar y coordinar tareas. Sin el uso de threads hay aplicaciones
que son casi imposibles de programar:

Las que tienen tiempos de espera importantes entre etapas

Las que consumen muchos recursos de CPU e impiden que el procesador atienda
simultneamente otros eventos o peticiones del usuario (por ejemplo, un chat)

Java soporta la ejecucin paralela de varios threads. Los threads en una misma mquina
virtual comparten recursos (por ejemplo memoria). Los threads en varias mquinas virtuales
necesitan mecanismos de comunicacin para compartir informacin. Hay dos modos de
conseguir threads en Java:

Extender la clase Thread,

Implementando la interface Runnable.

Creacin extendiendo la clase Thread.

El nuevo thread se crea extendiendo la clase Thread y redefiniendo el mtodo run().


public class ClienteThread extends Thread {
// Atributos y mtodos de la clase . . .
public void run() {
// cdigo propio del thread
}
}
public class Test {
public static void main(String[] args){
while (true) {
socketClient = listener.accept();
ClienteThread c =new ClienteThread(socketClient);
c.start();
}
}
}

Creacin implementando la interface Runnable.

El constructor de la clase Thread recibe un argumento que debe ser una instancia de una
clase que implementa la interface Runnable, implementando el mtodo run().
public class ClienteThread implements Runnable {
// Atributos y mtodos de la clase . . .
public void run(){
// cdigo propio del thread
}
}
public class Test{
public static void main(String args[]){
ClienteThread r = new ClienteThread();
Thread t = new Thread(r);
t.start();
}
}

7
Sesin de laboratorio
Ejercicio 3: Threads-1

En este ejercicio vamos a aadir a nuestro servidor la funcionalidad de atender a varios


clientes al mismo tiempo (concurrentemente). As podremos comprobar que los comandos
REGISTER y CLOSE, programados anteriormente, funcionan tal y como se esperaba.
Tambin podremos aadir ms comandos a nuestro Chat.

Tal como funciona nuestra aplicacin en este momento para cada ClienteChat que se
conecta a ServidorChat se crea un objeto de la clase Cliente donde se almacena su nick
(name) y el socket asignado en tiempo de ejecucin en la mquina servidor para comunicarse
con la mquina cliente (ClienteChat.java), etc.

a) Modifica el cdigo de ServidorChat.java y de Cliente.java de forma que se cree


un thread para cada ClienteChat.java que se conecte a ServidorChat.java.

Nota: Si dentro del mtodo run() de un thread utilizas mtodos que generan
excepciones, es necesario poner ese cdigo dentro de un bloque try/catch

b) Comprueba que los comandos REGISTER y CLOSE, programados anteriormente,


funcionan tal y como se esperaba.

Chat en Java 4
Estudio Previo
3. Estudio del ejemplo de uso de Threads Ejemplo.java (que te facilitamos junto
con el cdigo y que tambin puedes encontrar en la documentacin de Wikipedia).
4. Modifica el ejemplo para que muestre por pantalla el nombre del thread que se est
ejecutando.
5. Ejecuta el nuevo ejemplo varias veces, analzalo y describe cundo cada uno de los
threads ejecutan cdigo, si aunque no printen por pantalla tienen asignada la CPU,
qu printa por pantalla cada thread y si ambos threads finalizan cuando se ejecuta la
sentencia System.exit(0) (trelo a la sesin de laboratorio en papel)

Nota: Si es necesario repasa el tutorial Threads (Scheme) de javaHispano.

Comentarios
javaHispano
El web javaHispano (http://www.javahispano.org) mantiene noticias, manuales, tutoriales de
Java en castellano.

El manual de esta parte de la prctica se encuentra en la seccin Java / Tutoriales / J2SE


(http://www.javahispano.org/tutorials.type.action?type=j2se) bajo el nombre Threads
(Scheme)

Sesin de laboratorio
Ejercicio 4: Threads-2

En este ejercicio vamos a aadir a nuestro chat que la parte de cliente sea capaz de leer del
socket y de leer de teclado concurrentemente (en un chat en cualquier momento alguien

8
puede enviarte un mensaje mientras ests escribiendo t un nuevo mensaje o pudiendo un
nuevo comando al servidor).

a) Basndote en el cdigo de Ejemplo.java modifica el cdigo de ClienteChat.java,


para que en el main se cree un objeto ClienteChat, se creen dos threads de ese objeto, uno
de los threads ejecute el mtodo sendCommand() y el otro thread el mtodo
listenServer().

El mtodo sendCommand() tendr el cdigo del ClienteChat.java del ejercicio 3 que se


encarga de leer comando del usuario y enviarlo a la parte Servidor de nuestra aplicacin

El mtodo listenServer() leer continuamente lo que le enva el servidor


(Cliente.java) y cuando el servidor enve el mensaje de despedida (Bye Bye ) cerrar
el socket y la aplicacin de ClienteChat.java.

Chat en Java 5
Estudio Previo
1. Estudio de la clase String de la seccin 4.2. Strings and Characters del libro Java in
a Nutshell, 4th Edition de David Flanagan (en el apartado comentarios tienes cmo
acceder on-line al contenido del libro).
Nota: No es necesario para realizar la prctica estudiar ninguno de los
subapartados 4.2.X.

2. Estudio los siguientes mtodos de la clase String:


a. int indexOf(int ch)
b. boolean startsWith(String prefix)
c. String substring(int beginIndex)
d. String substring(int beginIndex, int endIndex)

Nota: Tienes un ejemplo de cdigo de la seccin 4.2. Strings and Characters


del libro Java in a Nutshell, 4th Edition de David Flanagan. Tambin puedes
utilizar la Documentacin en lnea de las clases del SDK versin 1.4 (en el
apartado comentarios tienes cmo acceder on-line)

Comentarios
Java in a Nutshell, 4th Edition

El libro Java in a Nutshell, 4th Edition de David Flanagan


(http://proquest.safaribooksonline.com/0596002831) est accesible on-line desde la
biblioteca de la UPC (http://bibliotecnica.upc.edu/).

Puedes consultar el libro tanto desde un PC conectado a la red de la UPC como desde fuera
de la UPC (en este caso debes configurar tu navegador tal y como explica el link Accs
remot http://bibliotecnica.upc.es/remot/)

Documentacin en lnea de las clases del SDK versin 1.4

API del SDK http://java.sun.com/j2se/1.4/docs/api/index.html)

9
Sesin de laboratorio
Ejercicio 5: La clase String

En este ejercicio vamos a aadir a nuestro chat nuevos comandos. Los comandos son los
siguientes:

mensaje

Este comando enva un mensaje a todos los usuarios conectados en este momento al
chat. El mensaje no debe empezar ni por el carcter del comando SEND_CLIENT_LIST
(:), ni por el REGISTER ([), ni por el CLOSE (]), ni por el PRIVADO (/, reservado
para un futuro comando) Este mensaje aparece en cada una de las pantallas de los
usuarios conectados y la pantalla del usuario conectado muestra:

nickOrigen: mensaje

/nickDestino mensaje

Este comando enva un mensaje privado al usuario cuyo nick equivale al nickDestino
especificado en el comando. Este mensaje nicamente aparece en la pantalla del usuario
que enva el mensaje y la pantalla del usuario destinatario muestra:

Privado de nickOrigen a nickDestino: mensaje

a) Modifica el cdigo de ServidorChat.java, Cliente.java y de ClienteChat.java


para que soporte estos nuevos comandos.

Ejercicio 6: Mejorando la aplicacin

En este ejercicio se trata de mejorar la aplicacin del chat que tenemos con algn o algunos
detalles que se te ocurran. Por ejemplo: que no se permita a un usuario registrarse con un
nick de un cliente ya registrado, aadir un nuevo comando, aadir interficie grfica a nuestra
aplicacin, etc

10

También podría gustarte