0Pricing
Lua Academy · Aula

Construindo um cliente

Solicite dados a um servidor.

Construindo um cliente é uma aula grátis de Lua Academy no CoddyKit. Esta é a aula 2 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 Cliente

Um cliente TCP segue um ciclo de vida claro: criar um soquete, conectar-se a um servidor, trocar dados e depois fechar.

No LuaSocket, cada etapa é uma chamada de método, e qualquer uma delas pode falhar. Um cliente bem escrito verifica cada valor retornado e libera seu soquete em qualquer caminho de erro.

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

Conectando com Segurança

Defina um tempo limite de conexão antes de chamar connect para que um host indisponível não bloqueie seu programa. Alguns segundos é o usual.

Se connect retornar nil, registre o erro e aborte. Nunca presuma que a negociação foi bem-sucedida.

client:settimeout(5)
local ok, err = client:connect("127.0.0.1", 8080)
if not ok then
  client:close()
  error("connect failed: " .. err)
end

Usando socket.connect

Para o caso comum, socket.connect(host, port) combina a criação e a conexão. Ele retorna um objeto cliente pronto ou nil e um erro.

Isso é conciso, mas não oferece a oportunidade de definir um tempo limite antes da negociação; portanto, prefira a forma explícita em redes não confiáveis.

local socket = require("socket")
local client, err = socket.connect("example.com", 13)
if not client then error(err) end

Enviando uma Requisição

Depois de se conectar, escreva os bytes da sua requisição com send. Muitos protocolos de texto delimitam as linhas com retorno de carro + nova linha (\r\n).

Como TCP é um fluxo, finalize cada mensagem lógica de forma clara para que o servidor saiba onde ela termina.

local msg = "PING\r\n"
local sent, err = client:send(msg)
if not sent then error("send failed: " .. err) end

Lendo uma Resposta por Linha

Para protocolos baseados em linhas, use um laço de leitura com o padrão "*l". Cada chamada retorna uma linha sem o seu terminador.

Em caso de nil, examine o erro: "closed" significa que o servidor encerrou a conexão, enquanto "timeout" significa que nenhum dado chegou a tempo.

client:settimeout(5)
local line, err = client:receive("*l")
if line then
  print("server said:", line)
else
  print("recv error:", err)
end

Lendo uma Resposta Completa

Os protocolos de requisição e resposta costumam ler tudo até que o servidor feche a conexão. Use "*a" para capturar o corpo completo.

Se você fechar parcialmente primeiro o lado de envio com shutdown("send"), o servidor verá o fim da entrada e poderá concluir a resposta.

client:send("GET DATA\r\n")
client:shutdown("send")
local body, err = client:receive("*a")
print(#(body or ""), "bytes received")

Enquadramento de Tamanho Fixo

Os protocolos binários costumam prefixar cada mensagem com seu tamanho. Leia primeiro o cabeçalho de tamanho e depois leia exatamente essa quantidade de bytes.

Passar um número para receive bloqueia até que essa quantidade chegue ou o soquete apresente um erro, proporcionando um enquadramento preciso no fluxo de bytes.

local header = client:receive(4)
local len = string.unpack(">I4", header)
local payload = client:receive(len)

Um Cliente de Eco Completo

Este é o fluxo completo: conectar, enviar uma linha, ler a linha ecoada e fechar. Esse é o formato canônico de um cliente LuaSocket.

Observe que toda chamada que pode falhar é protegida com assert por questão de brevidade, mas um cliente real trataria os erros de forma adequada.

local socket = require("socket")
local c = assert(socket.connect("127.0.0.1", 8080))
assert(c:send("hello\r\n"))
print(c:receive("*l"))
c:close()

Tratando Desconexões

Os servidores podem interromper as conexões a qualquer momento. Um send para uma extremidade remota fechada pode retornar nil, "closed", e receive retorna os dados parciais juntamente com o erro.

Trate "closed" como um estado terminal normal, não como uma falha. A lógica de reconexão deve ficar em um invólucro de novas tentativas ao redor do cliente.

local data, err, partial = client:receive("*a")
if err == "closed" then
  print("peer closed, got", #partial, "bytes")
end

Clientes Não Bloqueantes

Defina o tempo limite como 0 para um cliente totalmente não bloqueante. As chamadas retornam imediatamente e sinalizam "timeout" quando não é possível avançar.

Combine isso com socket.select para aguardar com eficiência a disponibilidade em muitos soquetes, sem usar um laço ocupado.

client:settimeout(0)
local r = socket.select({client}, nil, 5)
if #r > 0 then print(client:receive("*l")) end

Resolvendo Nomes de Host

Se você se conectar usando um nome de host, o LuaSocket fará a resolução por você. Para inspecionar ou armazenar em cache a resolução, chame socket.dns.toip ou socket.dns.getaddrinfo por conta própria.

Resolver uma vez e conectar-se usando o IP evita consultas repetidas de DNS em um laço intenso de reconexão.

local socket = require("socket")
local ip = assert(socket.dns.toip("example.com"))
local c = assert(socket.connect(ip, 80))

Verificação Rápida

Escolha a maneira correta de ler tudo o que um servidor envia até que ele feche a conexão.

Recapitulação

Você criou um cliente TCP de ponta a ponta: conectou-se com um tempo limite, delimitou e enviou requisições, leu respostas por linha, por quantidade de bytes ou do fluxo inteiro e fechou corretamente.

Você também viu o tratamento de desconexões, o modo não bloqueante com select e o armazenamento em cache de DNS. Em seguida, você escreverá o lado do servidor que responde a esses clientes.

Perguntas Frequentes

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

Sim — o texto completo de “Construindo um cliente” é 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 cliente”?

Solicite dados a um servidor. 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 2 de 4.

Quanto tempo leva a aula “Construindo um cliente”?

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