Módulo TCP
Este módulo proporciona funcionalidades para conexiones TCP y TCP+TLS desde scripts Lua. Ofrece soporte para comunicación con sockets crudos, lectura/escritura de cadenas, JSON y paquetes JSON con tamaño prefijado.
El módulo tcp permite:
-
Conexiones TCP simples con timeout configurable
-
Conexiones TLS
-
Lectura y escritura de cadenas simples
-
Lectura y escritura de JSON
-
Lectura y escritura de paquetes JSON con tamaño prefijado (para comunicación binaria segura)
-
Resolución DNS automática para conexiones TLS
Funciones Disponibles
Sección titulada «Funciones Disponibles»tcp.connect(host, port, [timeout_secs])
Sección titulada «tcp.connect(host, port, [timeout_secs])»Establece una conexión TCP simple con un servidor remoto.
Parámetros:
-
host(string): Dirección del host o IP del servidor -
port(number): Puerto TCP para la conexión -
timeout_secs(number, opcional): Timeout en segundos (por defecto: 5)
Valor de retorno:
-
Objeto
Connectionque puede usarse para lectura/escritura -
Lanza error en caso de fallo o timeout
Ejemplo:
-- Conectar a un servidor en el puerto 8080 con timeout de 10 segundoslocal conn = tcp.connect("servidor.exemplo.com", 8080, 10)
-- Conectar con timeout por defecto (5 segundos)local conn2 = tcp.connect("192.168.1.100", 3000)tcp.connect_tls(host, port, [timeout_secs])
Sección titulada «tcp.connect_tls(host, port, [timeout_secs])»Establece una conexión TLS (SSL) con un servidor remoto.
Parámetros:
-
host(string): Dirección del host del servidor -
port(number): Puerto TLS para la conexión -
timeout_secs(number, opcional): Timeout en segundos (por defecto: 5)
Valor de retorno:
-
Objeto
TlsConnectionque puede usarse para lectura/escritura -
Lanza error en caso de fallo o timeout
Ejemplo:
-- Conectar vía TLS en el puerto 443local conn = tcp.connect_tls("api.exemplo.com", 443)
-- Conectar con timeout personalizadolocal conn2 = tcp.connect_tls("servidor-seguro.com", 8443, 15)tcp.send(data)
Sección titulada «tcp.send(data)»Envía datos a través de la última conexión TCP abierta con la función connect(). Esta función se mantiene por compatibilidad con versiones anteriores. Para mayor claridad y control, prefiera la forma local conn = connect("host", porta) y use los métodos del objeto de conexión devuelto (ej: conn:write_json_packet()).
Parámetros:
data(string): Datos a enviar
Valor de retorno:
-
nilen caso de éxito -
Lanza error si no hay conexión activa
Nota: Esta función usa la última conexión TCP abierta con la función connect(). Es útil para scripts simples que mantienen una única conexión.
Ejemplo:
-- Primero establece una conexiónlocal conn = tcp.connect("servidor.exemplo.com", 8080)
-- Envia datossend("GET / HTTP/1.1\r\nHost: servidor.exemplo.com\r\n\r\n")tcp.recv()
Sección titulada «tcp.recv()»Recibe datos de la última conexión TCP abierta con la función connect() y almacenada en el registro Lua. Esta función se mantiene por compatibilidad con versiones anteriores. Para mayor claridad y control, prefiera la forma local conn = connect("host", porta) y use los métodos del objeto de conexión devuelto (ej: conn:read_str() o conn:read_json_packet()).
Parámetros:
- Ninguno
Valor de retorno:
-
stringcon los datos recibidos -
Lanza error si no hay conexión activa
Nota:
-
Esta función usa la última conexión TCP abierta con la función
connect(). Es útil para scripts simples que mantienen una única conexión. -
Lee hasta 8192 bytes por llamada. Para lectura completa, puede ser necesario llamar múltiples veces.
Ejemplo:
-- Recebe respostalocal resposta = tcp.recv()print("Resposta recebida:", resposta)Métodos de los Objetos Connection
Sección titulada «Métodos de los Objetos Connection»Los objetos devueltos por connect() y connect_tls() poseen los siguientes métodos:
conn:read_str()
Sección titulada «conn:read_str()»Lee una cadena completa del socket hasta EOF.
Valor de retorno:
-
stringcon los datos leídos -
Lanza error en caso de fallo de lectura
Ejemplo:
local conn = tcp.connect("servidor.exemplo.com", 8080)local dados = conn:read_str()print("Dados recebidos:", dados)conn:read_json()
Sección titulada «conn:read_json()»Lee una cadena del socket e interpreta como JSON.
Valor de retorno:
-
Valor Lua decodificado del JSON
-
Lanza error si los datos no son JSON válido
Ejemplo:
local conn = tcp.connect("api.exemplo.com", 3000)local dados_json = conn:read_json()
-- Acessar dados decodificadosprint("Status:", dados_json.status)print("Mensagem:", dados_json.message)conn:read_json_packet()
Sección titulada «conn:read_json_packet()»Lee un paquete JSON con tamaño prefijado (formato binario).
Formato del paquete:
-
4 bytes (uint32): Tamaño de los datos JSON
-
N bytes: Datos JSON serializados
Límite de tamaño: 512KB (512.000 bytes)
Valor de retorno:
-
Valor Lua decodificado del JSON
-
Lanza error si el paquete es demasiado grande o JSON inválido
Ejemplo:
local conn = tcp.connect("servidor-binario.com", 9000)local pacote = conn:read_json_packet()print("Pacote recebido:", pacote)conn:write_json_packet(packet)
Sección titulada «conn:write_json_packet(packet)»Escribe un paquete JSON con tamaño prefijado (formato binario).
Parámetros:
packet(cualquier valor Lua): Datos a serializar como JSON
Valor de retorno:
-
nilen caso de éxito -
Lanza error en caso de fallo de serialización o escritura
Ejemplo:
local conn = tcp.connect("servidor-binario.com", 9000)
-- Enviar um pacote JSONlocal dados = { comando = "atualizar", id = 123, valores = {10, 20, 30}}conn:write_json_packet(dados)Información Adicional
Sección titulada «Información Adicional»Timeout Configurable
Sección titulada «Timeout Configurable»Todas las funciones de conexión aceptan timeout personalizado. Si no se especifica, usa 5 segundos por defecto.
Resolución DNS Automática
Sección titulada «Resolución DNS Automática»La función connect_tls() resuelve automáticamente el nombre del host a una dirección IP antes de establecer la conexión.
Tamaño Máximo de Paquete
Sección titulada «Tamaño Máximo de Paquete»Los paquetes JSON con tamaño prefijado tienen un límite de 512KB para prevenir ataques de denegación de servicio.
Ejemplos de Uso
Sección titulada «Ejemplos de Uso»Comunicación HTTP Simple
Sección titulada «Comunicación HTTP Simple»function fazer_requisicao_http(host, porta, caminho) local conn = tcp.connect(host, porta, 10)
-- Enviar requisição HTTP local requisicao = string.format( "GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", caminho, host )
-- Usar o método send (conexão está no registro) tcp.send(requisicao)
-- Ler resposta local resposta = tcp.recv()
-- Extrair corpo da resposta (simplificado) local corpo = resposta:match("\r\n\r\n(.+)$")
return corpoendCliente de API JSON
Sección titulada «Cliente de API JSON»function consultar_api_json(endpoint, dados) local conn = tcp.connect_tls("api.exemplo.com", 443)
-- Enviar dados como pacote JSON conn:write_json_packet({ endpoint = endpoint, dados = dados, timestamp = os.time() })
-- Aguardar resposta local resposta = conn:read_json_packet()
return respostaend
-- Exemplo de usolocal resultado = consultar_api_json("/usuarios", {id = 123})if resultado.success then print("Usuário:", resultado.usuario.nome)endMonitorización de Servicio TCP
Sección titulada «Monitorización de Servicio TCP»function verificar_servico_tcp(host, porta) local inicio = os.time() -- with_coroutine aceita a função e seus argumentos, retornando (result, err) local conn, err = with_coroutine(tcp.connect, host, porta, 5)
if not err and conn then local tempo_resposta = os.time() - inicio
-- Testar comunicação básica conn:write_json_packet({ping = true}) local resposta = conn:read_json_packet()
if resposta and resposta.pong then return { status = "online", tempo_resposta = tempo_resposta, versao = resposta.versao } end end
return { status = "offline", erro = err -- err contém a mensagem de erro quando with_coroutine falha }endComunicación Bidireccional
Sección titulada «Comunicación Bidireccional»function chat_client(host, porta) local conn = tcp.connect(host, porta)
-- Thread para receber mensagens local function receber_mensagens() while true do local mensagem = conn:read_json_packet() print("Recebido:", mensagem.texto) end end
-- Thread para enviar mensagens (simplificado) local function enviar_mensagens() while true do io.write("Digite mensagem: ") local texto = io.read() if texto == "sair" then break end
conn:write_json_packet({ tipo = "mensagem", texto = texto, timestamp = os.time() }) end end
-- Em um ambiente real, isso seria feito com corrotinas -- Esta é uma simplificação para demonstraçãoend