0Pricing
Lua Academy · Lección

Crear un servidor

Acepte conexiones entrantes

Crear un servidor es una lección gratuita de Lua Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Lua Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Lua Academy incluye 4 lecciones en total.

Ciclo de vida del servidor

Un servidor TCP se asocia a una dirección, escucha las conexiones y, después, entra en un bucle para aceptarlas y atender a los clientes.

En LuaSocket se crea un objeto maestro con socket.tcp(), se convierte en un servidor de escucha mediante bind/listen y se extraen los clientes de la cola con accept.

local socket = require("socket")
local server = assert(socket.tcp())

Asociación a un puerto

server:bind(host, port) reserva una dirección local. Use "*" o "0.0.0.0" para aceptar conexiones en todas las interfaces, o "127.0.0.1" para aceptar únicamente conexiones locales.

bind falla con "address already in use" si otro proceso ya ocupa el puerto.

server:setoption("reuseaddr", true)
local ok, err = server:bind("*", 8080)
if not ok then error("bind failed: " .. err) end

Escucha de clientes

server:listen(backlog) marca el socket como pasivo y empieza a poner en cola los handshakes entrantes. El backlog es el número máximo de conexiones pendientes.

La forma abreviada socket.bind(host, port, backlog) realiza el bind y el listen en una sola llamada y devuelve un objeto servidor listo para usar.

local socket = require("socket")
local server = assert(socket.bind("*", 8080, 32))
print("listening on", server:getsockname())

Aceptación de una conexión

server:accept() bloquea la ejecución hasta que se conecta un cliente y, entonces, devuelve un objeto cliente TCP completamente nuevo para ese par. El socket del servidor continúa escuchando.

En un socket servidor con tiempo de espera configurado, accept devuelve nil, "timeout", lo que permite intercalar otras tareas.

local client, err = server:accept()
if client then
  print("client from", client:getpeername())
end

Atención de un cliente

Después de accept, trate el objeto devuelto exactamente igual que un socket cliente: reciba solicitudes con receive y envíe respuestas con send.

Asigne al socket de cada cliente su propio tiempo de espera para que un cliente lento no pueda bloquear todo el servidor.

client:settimeout(10)
local line = client:receive("*l")
if line then client:send(line .. "\n") end
client:close()

El bucle de aceptación

Un servidor iterativo clásico repite indefinidamente este proceso: aceptar un cliente, atenderlo, cerrarlo y volver a empezar. Esto permite atender a un cliente cada vez.

Es sencillo y correcto, pero no puede atender a varios clientes simultáneamente, ya que una solicitud lenta bloquea a todas las que esperan detrás.

while true do
  local c = server:accept()
  if c then
    local msg = c:receive("*l")
    if msg then c:send(msg .. "\r\n") end
    c:close()
  end
end

Un servidor de eco mínimo

Al unir todas las piezas, un servidor de eco se asocia a una dirección, empieza a escuchar y, después, repite la primera línea de cada cliente.

Este es el servidor de LuaSocket completo más pequeño y un objetivo útil para el cliente que creó anteriormente.

local socket = require("socket")
local s = assert(socket.bind("*", 8080))
while true do
  local c = s:accept()
  c:send((c:receive("*l") or "") .. "\r\n")
  c:close()
end

Concurrencia con select

Para atender a muchos clientes a la vez sin usar hilos, utilice socket.select. Devuelve los sockets que están listos para leer, incluido el servidor de escucha cuando hay un cliente nuevo esperando.

Administre una tabla de clientes activos y procese únicamente aquellos que tienen datos, manteniendo ágil un bucle de eventos de un solo hilo.

local readable = socket.select(watch, nil, 1)
for _, sock in ipairs(readable) do
  if sock == server then
    table.insert(watch, server:accept())
  end
end

Aceptación no bloqueante

Establezca server:settimeout(0) para que accept nunca bloquee la ejecución. Combínelo con select para llamar a accept únicamente cuando el socket de escucha esté realmente listo para leer.

Esta es la base de un servidor escalable en un solo proceso que multiplexa cientos de conexiones.

server:settimeout(0)
local ready = socket.select({server}, nil, 5)
if #ready > 0 then
  local c = server:accept()
end

Gestión de errores del cliente

Los clientes pueden desconectarse de forma abrupta. Cuando receive devuelve nil, "closed" o un búfer parcial, elimine ese cliente de la tabla de sockets supervisados y cierre su socket.

No permita que una conexión defectuosa detenga el bucle de aceptación; aísle los fallos de cada cliente.

local data, err = client:receive("*l")
if err == "closed" then
  client:close()
  remove_from_watch(client)
end

Apagado limpio

Durante el apagado, deje de aceptar conexiones, cierre todos los sockets de clientes activos y, después, cierre el servidor de escucha para liberar el puerto.

Establecer reuseaddr al asociar el socket permite reiniciar de inmediato sin tener que esperar a que transcurra el periodo TIME_WAIT de TCP.

for _, c in ipairs(clients) do c:close() end
server:close()
print("server stopped")

Comprobación rápida

Elija la secuencia de llamadas que convierte un socket maestro recién creado en un socket de escucha funcional.

Resumen

Ha creado un servidor TCP: lo ha asociado con reuseaddr, ha iniciado la escucha con un backlog y ha usado un bucle con accept para atender a los clientes.

Ha visto el sencillo bucle iterativo y, después, cómo ampliarlo con socket.select para obtener concurrencia no bloqueante, además de aislar errores y realizar un apagado limpio. A continuación subirá de nivel hasta HTTP.

Preguntas frecuentes

¿La lección «Crear un servidor» es gratis?

Sí — el texto completo de «Crear un servidor» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Lua Academy, actualiza a CoddyKit PRO. El curso de Lua Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Crear un servidor»?

Acepte conexiones entrantes Practicas Lua Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Lua Academy?

No se requiere experiencia previa. Lua Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Crear un servidor»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Lua Academy?

Sí. Cada lección de Lua Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Conceptos básicos de TCP
  2. Crear un cliente
  3. Crear un servidor
  4. Solicitudes HTTP
← Volver a Lua Academy