0Pricing
Lua Academy · Aula

Construindo um servidor

Aceite conexões recebidas.

Construindo um servidor é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Lua Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Lua Academy inclui 4 aulas no total.

Ciclo de Vida do Servidor

Um servidor TCP associa-se a um endereço, aguarda conexões e depois repete o processo de aceitá-las e atender aos clientes.

No LuaSocket, você cria um objeto mestre com socket.tcp(), transforma-o em um servidor de escuta com bind/listen e retira os clientes da fila com accept.

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

Associando a uma Porta

server:bind(host, port) reserva um endereço local. Use "*" ou "0.0.0.0" para aceitar conexões em todas as interfaces, ou "127.0.0.1" para aceitar somente conexões locais.

A associação falha com "address already in use" se outro processo estiver usando a porta.

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

Aguardando Conexões de Clientes

server:listen(backlog) marca o soquete como passivo e começa a enfileirar as negociações recebidas. A fila de espera é o número máximo de conexões pendentes.

O atalho socket.bind(host, port, backlog) executa a associação e a escuta em uma única chamada, retornando um objeto servidor pronto.

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

Aceitando uma Conexão

server:accept() bloqueia até que um cliente se conecte e depois retorna um novo objeto cliente TCP para essa outra extremidade. O próprio soquete do servidor continua escutando.

Em um soquete de servidor com tempo limite definido, accept retorna nil, "timeout", o que permite intercalar outras tarefas.

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

Atendendo um Cliente

Depois de aceitar a conexão, trate o objeto retornado exatamente como um soquete cliente: receba requisições com receive e envie respostas com send.

Defina um tempo limite próprio para o soquete de cada cliente, para que um cliente lento não bloqueie o servidor inteiro.

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

O Laço de Aceitação

Um servidor iterativo clássico repete indefinidamente: aceita um cliente, atende-o, fecha-o e repete. Isso trata um cliente por vez.

É simples e correto, mas não consegue atender clientes simultâneos, pois uma requisição lenta bloqueia todos os clientes que estão atrás dela.

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

Um Servidor de Eco Mínimo

Reunindo tudo, um servidor de eco associa-se a um endereço, começa a escutar e depois repete a primeira linha de cada cliente de volta para ele.

Este é o menor servidor LuaSocket completo e um objetivo útil para o cliente que você criou 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

Concorrência com select

Para atender muitos clientes ao mesmo tempo sem usar threads, use socket.select. Ele retorna os soquetes prontos para leitura, incluindo o servidor de escuta quando há um novo cliente aguardando.

Você gerencia uma tabela de clientes ativos e processa apenas aqueles que têm dados, mantendo responsivo um laço de eventos de uma única thread.

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

Aceitação Não Bloqueante

Defina server:settimeout(0) para que a aceitação nunca bloqueie. Combine isso com select para chamar a aceitação somente quando o ouvinte estiver realmente legível.

Essa é a base de um servidor escalável de processo único que multiplexa centenas de conexões.

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

Tratando Erros dos Clientes

Os clientes podem se desconectar abruptamente. Quando receive retorna nil, "closed" ou uma área de memória parcial, remova esse cliente da tabela monitorada e feche seu soquete.

Nunca permita que uma conexão com falha derrube o laço de aceitação; isole as falhas de cada cliente.

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

Encerramento Limpo

Ao encerrar, pare de aceitar conexões, feche cada soquete de cliente ativo e depois feche o servidor de escuta para liberar a porta.

Definir reuseaddr no momento da associação permite reiniciar imediatamente, sem esperar o fim do período TCP TIME_WAIT.

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

Verificação Rápida

Escolha a sequência de chamadas que transforma um soquete mestre recém-criado em um ouvinte funcional.

Recapitulação

Você criou um servidor TCP: associou-o com reuseaddr, iniciou a escuta com uma fila de espera e repetiu accept para atender aos clientes.

Você viu o simples laço iterativo e depois o ampliou com socket.select para obter concorrência não bloqueante, além do isolamento de erros e do encerramento limpo. Em seguida, você avançará para HTTP.

Perguntas Frequentes

A aula “Construindo um servidor” é grátis?

Sim — o texto completo de “Construindo um servidor” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Lua Academy, atualize para CoddyKit PRO. O curso de Lua Academy inclui 4 aulas no total.

O que vou aprender em “Construindo um servidor”?

Aceite conexões recebidas. Você pratica Lua Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Lua Academy?

Nenhuma experiência prévia é necessária. Lua Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Construindo um servidor”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Lua Academy?

Sim. Cada aula de Lua Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Fundamentos de TCP
  2. Construindo um cliente
  3. Construindo um servidor
  4. Solicitações HTTP
← Voltar para Lua Academy