Un servidor web sencillo en Java

Cuando cursé Redes en la carrera, una de las prácticas era implementar un servidor web sencillo en el lenguaje Java que pudiese responder a algunas sencillas peticiones HTTP. Lo esencial para realizar correctamente el ejercicio era:
– Que el servidor fuese multi-thread para poder atender a varios clientes a la vez
– Que al menos se implementasen las operaciones HEAD y GET
– Que se soportasen los formatos de archivo HTML, texto plano, GIF y JPEG
Había otras características opcionales que implementar, pero por ahora me voy a centrar en diseccionar un poco la versión “mínima” que tuvimos que desarrollar.
El proyecto para Netbeans lo puedes descargar en el siguiente enlace: ServidorWeb.zip
Recuerda que si tienes que realizar una práctica similar, bajarte el código y entregarlo tal cual no servirá para que aprendas nada y será una gran traba si pretendes superar una asignatura de redes. Investiga, modifícalo, búscale las cosquillas!!! 🙂

La clase principal es la clase “Servidor”, que también es la más pequeña porque solo crea el socket del servidor y se queda esperando a que lleguen conexiones. Si una llega, abre un nuevo hilo (thread) en el que se atenderá esa petición, mientras puede esperar a que lleguen otras. Cada una se procesará por separado y así pueden ser concurrentes.
Es importante destacar que el método usado para arrancar un thread sea “start()” en lugar de “run()”. Lo que en realidad sucede es que “start()” ejecuta lo mismo que “run()” en un hilo aparte, mientras que “run()” lo haría en el hilo padre, bloqueando el funcionamiento del resto del programa mientras no termine sus tareas.

Hay que fijarse también en que el puerto escogido para operar no sea uno de los reservados (de 0 a 1024), yo por ejemplo seleccioné el 8000. El timeout para las conexiones es de 30 segundos.

El siguiente punto en el que me quiero detener es precisamente el método “run()” de la clase “HiloTrabajo”. Aquí es donde se comenzarán a atender de verdad las peticiones de los clientes:

En él se inicializan los flujos de entrada (input) y salida (output), y se ha de vigilar que, en caso de que algo vaya mal o se alcance el límite de tiempo, los flujos se cierren, así como el socket de la conexión para que vuelva a estar libre. De ahí tanto try-catch anidado.
El método responder es el que leerá el contenido de las peticiones, las discriminará según su tipo e irá generando la respuesta. Está muy documentado por ser bastante largo, aclarando además todos los pasos en las partes menos entendibles.

Aclaro que no he incluido ningún tipo de control de errores en la entrada, y el programa es muy poco tolerante con la forma en que le llegan las peticiones, pero se puede probar con facilidad.
Si echas a correr el servidor (bien desde una terminal, bien desde el propio Netbeans) puedes conectarte a él desde una terminal.
Para hacer la prueba he creado un archivo “index.html” en mi home, que básicamente solo contiene la palabra “hello” y un salto de linea.
Desde el terminal:
$ nc localhost 8000
Ahora no puedes ver el prompt porque estás conectado al servidor y está esperando tu petición. Si no envías nada o tardas más de 30 segundos en hacerlo, te desconectará. Como lo estoy probando en local, tengo que incluir las rutas absolutas a los archivos que solicite. Una petición válida es:
GET /home/edm/index.html HTTP/1.0


Ojo! Las peticiones siempre terminan con una linea en blanco, así que tienes que pulsar Intro dos veces. Si lo haces, el servidor te responderá:

Por ahora solo están implementados los métodos HEAD y GET, así como los siguientes mensajes de control:
– 200 OK
– 404 Not Found
– 501 Not Implemented
El primero será el que se devuelva cuando la petición es correcta y los datos se pueden enviar. El segundo, cuando el recurso solicitado no exista y el tercero cuando se pida algo a lo que el servidor no puede responder.

Por ahora faltarían muchas funciones de las que se pedían adicionalmente en la práctica que yo tuve que hacer, pero espero poder añadirlas en post sucesivos y que podáis ir viendo el proceso.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s