¡Bienvenidos a Rustaceo.es! En esta serie de artículos, construiremos un servidor web desde cero en Rust, utilizando conceptos clave del lenguaje y aprovechando su seguridad y eficiencia. Por supuesto, todo con la temática Pokémon para hacerlo más divertido. 🚀
🎯 Objetivos del proyecto #
Antes de escribir una sola línea de código, definamos qué queremos lograr con nuestro servidor web:
- Servir contenido dinámico y estático: Permitirá responder con datos predefinidos o dinámicamente generados.
- Eficiencia y seguridad: Aprovecharemos el modelo de seguridad de Rust para evitar errores comunes.
- Escalabilidad: Empezaremos con un modelo simple y luego lo expandiremos con manejo de rutas y concurrencia.
🛠 Retos a superar #
Construir un servidor web desde cero implica enfrentar varios desafíos:
- Manejo de conexiones: Cómo recibir y procesar solicitudes HTTP desde un cliente.
- Formato de respuesta: Construir respuestas válidas en formato HTTP.
- Paralelismo y concurrencia: Hacer que nuestro servidor pueda manejar múltiples peticiones simultáneamente.
Pero no nos preocupemos aún por todo esto. En esta primera parte, solo vamos a centrarnos en levantar un servidor básico que pueda recibir conexiones.
🏗 Primera implementación: servidor básico #
Empecemos creando la estructura básica de nuestro servidor. Para ello, utilizaremos std::net
para manejar sockets y aceptar conexiones entrantes.
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
fn manejar_conexion(mut stream: TcpStream) {
let mut buffer = [0; 512];
stream.read(&mut buffer).unwrap();
let respuesta = "HTTP/1.1 200 OK\r\n\r\n¡Bienvenido al Servidor Pokémon!";
stream.write(respuesta.as_bytes()).unwrap();
stream.flush().unwrap();
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
println!("Servidor Pokémon escuchando en http://127.0.0.1:7878");
for stream in listener.incoming() {
let stream = stream.unwrap();
manejar_conexion(stream);
}
}
🔍 Explicación del código #
TcpListener::bind("127.0.0.1:7878")
: Creamos un servidor que escucha en el puerto 7878.listener.incoming()
: Iteramos sobre las conexiones entrantes.manejar_conexion(stream)
: Procesamos la conexión, leyendo la solicitud y respondiendo con un mensaje estático.
🚀 ¿Qué sigue? #
En esta primera versión, el servidor acepta peticiones y responde con un mensaje fijo. En la próxima parte, agregaremos manejo de rutas y procesamiento de peticiones, para que pueda responder dinámicamente según lo que el cliente solicite.
¡Hasta la próxima, Rustaceos!