02 - Servidor HTTP sobre sockets

HTTP es un protocolo de aplicación sobre TCP: el cliente envía una petición con formato definido y el servidor responde con una respuesta también con formato definido. Como el formato es texto, un servidor HTTP puede construirse con los sockets del tema anterior.

GET /books/42 HTTP/1.1
Host: localhost:8080
Accept: application/json

  • Línea de petición: método, ruta y versión.
  • Cabeceras: pares Nombre: valor (una por línea).
  • Línea en blanco: separa cabeceras y cuerpo (el cuerpo puede estar vacío en un GET).

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 39

{"id":42,"title":"Código limpio"}

  • Línea de estado: versión, código de estado y frase.
  • Cabeceras: Content-Type, Content-Length…
  • Cuerpo: los datos, en el formato que anuncia Content-Type.
Código Significado
200 OK
201 Recurso creado
400 Petición mal formada
404 No encontrado
500 Error del servidor

public class HttpServer {
    public static void main(String[] args) throws IOException {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            while (true) {
                try (Socket socket = serverSocket.accept()) {
                    handle(socket);
                }
            }
        }
    }

    private static void handle(Socket socket) throws IOException {
        BufferedReader in = new BufferedReader(
                new InputStreamReader(socket.getInputStream()));
        PrintWriter out = new PrintWriter(socket.getOutputStream());

        String requestLine = in.readLine();          // GET /books/42 HTTP/1.1
        String route = requestLine.split(" ")[1];
        readHeaders(in);                             // hasta la línea vacía

        String body = "{\"message\":\"Hello from " + route + "\"}";
        out.print("HTTP/1.1 200 OK\r\n");
        out.print("Content-Type: application/json\r\n");
        out.print("Content-Length: " + body.getBytes().length + "\r\n");
        out.print("\r\n");
        out.print(body);
        out.flush();
    }

    private static void readHeaders(BufferedReader in) throws IOException {
        String line;
        while ((line = in.readLine()) != null && !line.isEmpty()) {
            // procesar cada cabecera si hace falta
        }
    }
}

Con un navegador o curl contra http://localhost:8080/books/42 se obtiene la respuesta JSON.

Necesidad Solución que llega después
Atender varias peticiones a la vez Hilos (tema siguiente)
Parsear rutas, parámetros y cuerpos completos Servlets y Tomcat
Devolver archivos, páginas, errores estándar El contenedor lo resuelve
Este servidor cumple el protocolo, pero es secuencial: una sola petición a la vez. Es la motivación exacta de por qué los servidores reales usan un pool de hilos.
  • clase/daw/si/1eval/servidorhttp3.txt
  • Última modificación: 2026/10/12 12:55
  • por cesguiro