Práctica de Ejecución Remota en Java 2016 v1.0 1. Descripción La práctica consiste en programar un servidor y un cliente en Java que permitan ejecutar comandos de forma remota. El servidor debe implementar un protocolo que permita: • Ejecutar un comando • Ver qué comandos siguen ejecutando en el servidor (sean del cliente que sean). • Matar un comando que está ejecutando (de cualquier cliente). • Cambiar el shell utilizado para ejecutar los comandos. • Pedir que el servidor termine de ejecutar. El cliente debe: • Leer líneas de la entrada y, para cada línea ejecutar el comando en el servidor y, cuando este comando termine, imprimir la salida (stdout y stderr) de dicho comando. • Si el comando es cmds el cliente ha de pedir la lista de comandos al servidor e imprimir el resultado. La lista debe ir numerada asignando un número único a cada comando. • Si el comando es stop n el cliente debe pedir al servidor que se mate el comando numerado como n en la lista actual de comandos. • Si el comando es interp xxxxx entonces ha de pedir al servidor que el shell a utilizar para este cliente sea xxxxx de ahora en adelante. (Inicialmente se utiliza /bin/sh). • Si el comando es quit el cliente ha de terminar de ejecutar. • Si el comando es exit el cliente ha de pedir al servidor que termine ordenadamente. Naturalmente, debe ser posible utilizar el servidor desde varios clientes al mismo tiempo. Cuando el servidor termina ordenadamente, los comandos de otros clientes en curso deben acabar de ejecutar, pero no se aceptan nuevos comandos y cuando todos los que están en curso terminan, el servidor termina. Tanto el servidor como el cliente reciben un único argumento con el puerto en que ha de escuchar el servidor y el puerto al que ha de conectarse el cliente respectivamente. En ambos casos, y dado que ejecutamos comandos, utilizaremos localhost como dirección. El servidor se debe poder ejecutar como en el ejemplo que sigue: $ jsh 6666 started Como puede verse, el servidor se queda ejecutando en primer plano. -2- El cliente debe poder ejecutarse como sigue: $ jrsh 666 > date Thu Mar 31 12:09:06 CEST 2016 > cmds 5 sleep 3600 > stop 5 > cmds > interp /bin/bash > quit Los mensajes deben tener: • los enteros aplanados en little endian en 4 bytes. • los nombres y strings codificados en UTF-8 Todo el fuente debe estar contenido en los paquetes lab16.XXX.server y lab16.XXX.client. En ambos casos, XXX debe ser tu nombre de usuario en Linux. Cualquier otro paquete auxiliar que nececesites debe estar dentro de lab16.XXX utilizando el mismo convenio para XXX. El código debe estar limpio y debe utilizar las técnicas de orientación a objectos donde corresponda. Las partes opcionales permiten tener nota extra pero la parte básica permite alcanzar la máxima puntuación si está hecha correctamente. 2. Opcional 1 Implementar unidades de JUnit para todos los elementos utilizados y documentar claramente el javadoc todos los elementos, incluyendo una guía de uso. 3. Opcional 2 Permitir que la salida de un comando se muestre cuando dicho comando termine. En este caso, tras enviar una petición de ejecución de comando al servidor, el cliente no espera y pasa a leer el siguiente comando de la entrada. En cuanto se reciben las respuestas con el resultado de las ejecuciones se muestran estos en el cliente (aunque se esté leyendo una línea en ese instante). Esto requiere multiplexar las peticiones en el cliente.