1. El fichero Ej1.java es un programa que tomará una URL como parámetro, accederá a ella y leerá su contenido mostrándolo por pantalla. Deberemos añadir código para:
a) Crear un objeto URL para la url especificada en el método creaURL, capturando las posibles excepciones que se pueden producir si está mal formada y mostrando el mensaje de error correspondiente por la salida de error. Compilar y comprobar que ocurre al pasar URLs correctas e incorrectas.
b) Abrir un flujo de entrada desde la URL indicada en el método leeURL. Deberemos obtener un InputStream de la URL, y convertirlo a un objeto BufferedReader, aplicando las transformaciones intermedias necesarias, para poder leer de la URL los caracteres línea a línea. Comprobar que lee correctamente algunas URLs conocidas. Descomentar el bloque de código que realiza la lectura de la URL.
2. (CHAT) En el fichero Ej2.java haremos lo mismo que en el caso anterior, pero en lugar de leer una página web mediante una URL, lo haremos conectándonos a la máquina donde está alojada mediante sockets. Para ello, vamos a crear una clase ConexionSocket en el paquete es que maneje una conexión establecida mediante sockets permitiéndonos leer y escribir líneas de texto en el socket. Esta clase la reutilizaremos posteriormente para nuestro chat. En este caso deberemos tener en cuenta los siguientes aspectos:
GET /index.html
El fichero Ej2.java será el conductor que nos permita probar la clase ConexionSocket, que es la que deberemos crear. En el fichero es/ConexionSocket.java se proporciona una plantilla de dicha clase que deberemos completar. Se pide:
3. (CHAT) Realizar un chat sencillo en Java comunicado mediante sockets. Para ello deberemos crear los clientes del chat y un servidor que comunique los distintos clientes. Deberemos establecer el protocolo de comunicación entre clientes y servidor. Los distintos elementos de los mensajes se enviarán por líneas (separados por el carácter fin de línea). Distinguimos los siguientes tipos de mensajes:a) Añadir al constructor de la clase el código necesario para crear un socket que se conecte a la dirección y puerto especificados. Capturar las excepciones que sean necesarias para que compile correctamente, mostrando en cada caso el mensaje de error oportuno. Compilar y probar a conectar a distintas direcciones, viendo lo que ocurre cuando la conexión es aceptada, cuando es rechazada, o cuando no existe la máquina destino que hayamos indicado.
b) Crear en ambos constructores un objeto BufferedReader a partir del flujo de entrada del socket, y un objeto PrintStream a partir del flujo de salida. Estos objetos nos permitirán leer y escribir línea a línea en el socket con los métodos envia y recibe ya definidos. Descomentar de Ej2.java el bloque de código que realiza la lectura del socket, compilar y probar que funciona correctamente.
Mensaje | Respuesta del servidor | |
LOGIN (loginUsuario) |
L <login> <password> |
Si los datos son correctos: OK Si no: ERROR <mensaje de error> |
REGISTRO (registraUsuario) |
R <login> <password> |
Si puede registrar el nuevo usuario: OK Si no: ERROR <mensaje de error> |
MENSAJE ENVIADO (envia) |
<mensaje> |
- |
MENSAJE RECIBIDO (recibe) |
- |
<mensaje> |
Podemos distinguir dos fases: una primera fase en la que el cliente podrá enviar mensajes de LOGIN y de REGISTRO, hasta que el servidor acepte el LOGIN, momento en el que entrará en la fase de chat, en la que el cliente podrá enviar mensajes, y el servidor difundirá a todos los clientes conectados todos los mensajes que le lleguen de cualquier cliente.
La clase ClienteChat ubicada en el paquete chat proporciona métodos para enviar estos cuatro tipos de mensajes. Por otro lado tendremos la clase ServidorChat en el mismo paquete que tendrá que atender peticiones de los clientes.
La clase Ej3 será la clase principal de la aplicación cliente de chat, y la que se encargará de hacer de interfaz con el usuario, utilizando ClienteChat para invocar las distintas funciones del chat. Tanto cliente como servidor deberán seguir el protocolo anteriormente descrito. Se pide:
a) La clase ClienteChat utilizará la clase genérica ConexionSocket desarrollada en el ejercicio anterior para enviar los mensajes que acepta el servidor del chat. Estos son los métodos necesarios para la funcionalidad del chat, ¿qué ventaja tiene haber definido esta clase separando funcionalidad del chat (ClienteChat) y presentación (Ej3)?b) Ahora tenemos que desarrollar un servidor web que permita aceptar y atender peticiones de múltiples usuarios simultáneamente. ¿Qué tendremos que utilizar para que sea capaz de realizar múltiples tareas simultáneamente?
c) Vamos a crear el bucle principal del servidor en el constructor de la clase ServidorChat. Este bucle deberá aceptar peticiones de los clientes, y para cada una de ellas crear un objeto HiloServidor que se encargará de atenderla. Al aceptar una petición nos devolverá un objeto Socket para comunicarnos con el cliente que acaba de conectarse, por lo que deberemos proporcionar dicho socket al hilo que creemos para que este hilo se comunique con el cliente. La plantilla de la clase que deberemos completar se encuentra en chat\ServidorChat.java. Compilar y comprobar que el chat funciona correctamente. Se debe tener en cuenta que la clase ServidorChat a ejecutar está en un subpaquete, por lo que tendremos que poner el nombre completo de la clase incluyendo el paquete para cargarla con java (chat.ServidorChat).
d) Hemos visto que cada cliente es atendido por un hilo independiente. Pero, si lo que envía un cliente debe ser visto por los demás, ¿cómo se comunican los distintos hilos? Estudiar el código fuente del servidor y explicar el mecanismo que se usa para difundir los mensajes entre los usuarios conectados.
e) Por otro lado, si todos los hilos acceden de forma concurrente al Vector de usuarios registrados, ¿podríamos tener conflictos en el acceso a los elementos del Vector? (Consultar la API de la clase Vector) ¿Y si en lugar de un Vector utilizásemos un objeto ArrayList? Por lo tanto, ¿qué ventaja tendrá cada una de estas dos listas dinámicas? ¿Cuándo será más conveniente utilizar cada una de ellas?