0Pricing
Lua Academy · Leçon

Construire un serveur

Acceptez les connexions entrantes.

Construire un serveur est une leçon Lua Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Lua Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Lua Academy comprend 4 leçons au total.

Cycle de vie d'un serveur

Un serveur TCP associe une adresse, se met à l'écoute des connexions, puis accepte et sert les clients en boucle.

Dans LuaSocket, vous créez un objet maître avec socket.tcp(), le transformez en serveur à l'écoute avec bind/listen, puis récupérez les clients dans la file d'attente avec accept.

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

Associer un port

server:bind(host, port) réserve une adresse locale. Utilisez "*" ou "0.0.0.0" pour accepter les connexions sur toutes les interfaces, ou "127.0.0.1" pour les accepter uniquement en local.

L'association échoue avec "address already in use" si un autre processus utilise déjà le port.

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

Écouter les clients

server:listen(backlog) rend le socket passif et commence à mettre en file d'attente les poignées de main entrantes. La file d'attente représente le nombre maximal de connexions en attente.

Le raccourci socket.bind(host, port, backlog) effectue l'association et la mise à l'écoute en un seul appel, puis renvoie un objet serveur prêt à l'emploi.

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

Accepter une connexion

server:accept() bloque jusqu'à ce qu'un client se connecte, puis renvoie un tout nouvel objet client TCP pour ce pair. Le socket serveur lui-même continue d'écouter.

Sur un socket serveur doté d'un délai d'attente, accept renvoie nil, "timeout", ce qui vous permet d'intercaler d'autres tâches.

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

Servir un client

Après l'acceptation, traitez l'objet renvoyé exactement comme un socket client : utilisez receive pour les requêtes et send pour les réponses.

Attribuez au socket de chaque client son propre délai d'attente afin qu'un client lent ne puisse pas bloquer tout le serveur.

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

La boucle d'acceptation

Un serveur itératif classique boucle indéfiniment : accepter un client, le servir, le fermer, puis recommencer. Il ne traite ainsi qu'un seul client à la fois.

Cette approche est simple et correcte, mais elle ne peut pas servir des clients simultanément, car une requête lente bloque tous les clients qui attendent derrière elle.

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 serveur d'écho minimal

En réunissant ces éléments, un serveur d'écho associe une adresse, se met à l'écoute, puis renvoie en boucle la première ligne de chaque client.

C'est le plus petit serveur LuaSocket complet et une cible utile pour le client que vous avez créé précédemment.

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

Concurrence avec select

Pour servir plusieurs clients à la fois sans utiliser de threads, utilisez socket.select. Il renvoie les sockets prêts à être lus, notamment le serveur à l'écoute lorsqu'un nouveau client est en attente.

Vous gérez une table de clients actifs et ne traitez que ceux qui disposent de données, ce qui permet à une boucle d'événements mono-thread de rester réactive.

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

Acceptation non bloquante

Définissez server:settimeout(0) afin que l'acceptation ne bloque jamais. Associez cette configuration à select pour n'appeler accept que lorsque le socket à l'écoute est effectivement lisible.

C'est la base d'un serveur évolutif à processus unique qui multiplexe des centaines de connexions.

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

Gérer les erreurs des clients

Les clients se déconnectent parfois brutalement. Lorsque receive renvoie nil, "closed" ou un tampon partiel, retirez ce client de votre table de surveillance et fermez son socket.

Ne laissez jamais une connexion défaillante arrêter la boucle d'acceptation ; isolez les erreurs de chaque client.

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

Arrêt propre

Lors de l'arrêt, cessez d'accepter les connexions, fermez chaque socket client actif, puis fermez le serveur à l'écoute afin de libérer le port.

Définir reuseaddr au moment de l'association permet de redémarrer immédiatement sans attendre la fin de la période TCP TIME_WAIT.

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

Vérification rapide

Choisissez la séquence d'appels qui transforme un socket maître vierge en écouteur fonctionnel.

Récapitulatif

Vous avez créé un serveur TCP : associer une adresse avec reuseaddr, se mettre à l'écoute avec une file d'attente, puis boucler sur accept pour servir les clients.

Vous avez vu la simple boucle itérative, puis sa mise à l'échelle avec socket.select pour permettre une concurrence non bloquante, ainsi que l'isolation des erreurs et l'arrêt propre. Vous allez maintenant passer à HTTP.

Questions Fréquemment Posées

La leçon « Construire un serveur » est-elle gratuite ?

Oui — le texte complet de « Construire un serveur » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Lua Academy, passe à CoddyKit PRO. Le cours Lua Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Construire un serveur » ?

Acceptez les connexions entrantes. Tu pratiques Lua Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Lua Academy ?

Aucune expérience préalable n'est requise. Lua Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Construire un serveur » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Lua Academy ?

Oui. Chaque leçon Lua Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Bases de TCP
  2. Construire un client
  3. Construire un serveur
  4. Requêtes HTTP
← Retour à Lua Academy