Ir para conteúdo
Entre para seguir isso  
Mock

Aprendendo a usar lua socket.

Recommended Posts

Mock    32
Mock

Eu só repostei o tuto aqui por que tem muita gente que quer aprender e nao sabe que o topico foi postado na seçao de programaçao e esta procurando aqui por que pensa em essa ser a seção pra lua. Mesmo nao sendo o local 100% adequado eu respostei aqui e vo pedi pro mod de lá apagar o topico.

 

 

Lembrando que lua socket é conteudo MUITO avançado nao é para iniciantes ou intermediarios é para quem ja possue um conhecimento mais avançado em lua ou alguma outra linguagem e as aplicaçoes não sao para otserv (podem ser usadas em otserv mais nao foram feitas apenas para isso, ou seja lua socket não é restrito a otserv e sim programaçao lua).

 

Como eu vi muita gente me pedindo para ensinar lua socket entao decidi faze esse tutorial e repassar tudo que eu sei.

 

Lembrando que lua socket nao é para qualquer um.

 

Bom vamos lá.

O primeiro passo é instalar.

[spoiler=Instalaçao]
o primeiro passo é instalar o lua socket, nesse caso você deve ir até aqui:

--windows

-- linux e derivados

 

Extraia todas as
DLL
e a pasta
socket
e
lua
para a pasta do interpretador. (interpretador é o programa que esta executando o script lua)

Em caso de otserv joge na pasta do otsev
(na pasta mesmo nao venha inventar de por na pasta data!)

 

Em seguida no começo do seu script vc deve colocar:

require('socket')

Em caso de otserv vc coloca isso no global.lua ou no data.lua

Em otserv é bom por isso:

pcall(require,'socket')

Agora ja instalado vamos aprender a usar.

Vamos pensar em socket como:

[spoiler=18+]12455.jpg

 

Pensa no host como a mulher e o homen como o client. Eles querem trocar informaçoes geneticas (dados), mas para isso a mulher (host) tem que abrir para o homen entrar :coolface:

é mais ou menos essa pornografia que acontece quando vc liga seu pc.

  • O host abre uma conexão
  • O client pede pra entrar
  • O host aceita
  • Eles trocam dados

Quando se for fazer algo em socket nao pense em apenas um script e sim em 2 juntos, o que complica em socket é isso, nao é 1 script que você vai fazer e sim 2.

Vamos começar com um host simples, nesse caso ele vai apenas abrir a conexao:

require('socket') -- sempre o require
local host = socket.bind('*',1234)

Pronto você tem um server de qualquer coisa aberto, usando protoclo TCP (nao vou explicar a diferença de TPC/UDP so que UDP é mais rapido porem tcp é mais simples e seguro) na porta 1234.

no argumento 1 eu coloquei '*' isso seria o IP mais como é o IP do seu pc entao vc dexa '*'. (realmente eu nao entendi muito bem isso mais em fim dexa)

Agora use o outro lado do seu cerebro para o segundo script, o client.

Vamos conectar em nosso host assim:

require('socket') -- sempre o require
local client = socket.connect('localhost',1234)
if client then
   print('Conectado')
else 
   print('offline')
end

Pronto! se estiver online ele vai mostrar conectao e offline como offline, porem nao adianta ainda vc tentar abrir o server daquele jeito e tentar conectar pois o script é so abrir a conexao e em seguida terminar o mesmo vale pro client entao ainda nao da para testar.

Vamos ver como aceita a conexão:

require('socket') -- sempre o require
local host = socket.bind('*',1234)
print('Aguardando uma conexao!')
local user = host:accept()
print('Alguem se conectou!')

Nesse caso estamos abrindo a conexao e em seguida usei host:accept(), quem ja usou io.read sabe que enquanto alguem nao escrever nada na tela o script fica parado, o mesmo vale para isso, enquanto ninguem se conectar o script vai ficar esperando alguem se conectar para proseeguir, quando conectado ele retorna uma userdata que ai com ela vc pode enviar/receber dados. Agora ja da pra vc conectar com o client porem ele vai conectar e fexar!

 

Transferindo dados:

Primeiro execute esse host:

require('socket') -- sempre o require
local host = socket.bind('*',1234)
print('Aguardando uma conexao!')
local user = host:accept()
print('Alguem se conectou! aguardando dados')
print(user:receive())

Em seguida execute esse client:

require('socket') -- sempre o require
local client = socket.connect('localhost',1234)
if client then
   print('Conectado')
else 
   print('offline')
   os.exit()
end
print('Escreva algo')
client:send(io.read()..'\n')

Escreva algo com os 2 abertos (primeiro abra o host depois o client).

--- Depois de executado

Vc deve ter falado MASSA!! e parou o tutorial para brincar de escrever.

Vamos explicar comofas :coolface:

Primeiramente no host eu apenas adcionei: user:receive()

Essa funçao funciona assim:

(quem conectou):receive(tamanho)

O tamanho seria quantos bytes é para ser recebido, enquanto ninguem nao mandar nada ou nem um pacote de dados essa funçao vai parar o script até que alguem se conecte e envie algo.

 

Já no client

(conectado no servidor):send(msg)

 

Em msg é o que vc quer enviar (sempre em string!) e no final NAO ESQUEÇA DE COLOCAR \n

Por que você pode fazer assim:

client:send('o')
client:send('i')
client:send('\n')

Você pode ir acumulando informaçoes que vai ficar la esperando para ser enviadas até que coloque no final \n assim:

client:send('oi[b]\n[/b]')

Lembre-se quando for enviar algo NAO ESQUEÇA do \n no final.

Lembrando que tanto o server como o client podem trocar informaçoes. Vc pode fazer um server +/- assim:

require('socket') -- sempre o require
local host = socket.bind('*',1234)
print('Aguardando uma conexao!')
local user = host:accept()
print('Alguem se conectou! aguardando dados')
while true do
local mensagem, status = user:receive()
if status == 'closed' then
  break
end
print(mensagem)
end

E o client assim:

require('socket') -- sempre o require
local client = socket.connect('localhost',1234)
if client then
   print('Conectado')
else 
   print('offline')
   os.exit()
end
print('Escreva algo')
repeat
   client:send(io.read()..'\n')
until not client

Que assim vc pode mandar informaçoes sem parar para o server.

 

 

---- parte 2

 

Essa parte ja é mais complicadinha para alguns.

Vou mostrar a funçao getpeername

Ela é simples. Retorna o IP de quem conectou ou do server.

Assim:

local ip = client:getpeername()

Agora vamos usar o settimeout

(conexao):settimeout(delay)

Essa funçao tira o aquela travada que da quando se usa accept ou receive e seta um tempo de espera, vc pode colocar como exeplo:

client:settimeout(2)
client:receive()

Se em 2 segundos o você nao receber nem um pacote a funçao client:receive vai retornar: nil, 'timeout'

podendo fazer assim:

while true do
  client:settimeout(1)
  local msg,stat = client:receive()
  if stat == 'closed' then -- verificar se a conexão foi fechada
     break
  end
  if msg and stat ~= 'timeout' then
     print(msg)
  end 
end

Ou assim no

while true do
  client:settimeout(1)
  local msg,stat = client:receive()
  if stat == 'closed' then -- verificar se a conexão foi fechada
     break
  end
  if msg and stat ~= 'timeout' then
     print(msg)
  else
     client:send('RESPON DE AI KRA!\n')
  end
end

(lembre-se que isso nao é so para o client tambem vale IGUALMENTE para o server)

 

Assim podemos fazer um mini-chat:

 

Server:

local host = socket.bind('*',1234)
print('Aguardando uma conexao!')
local user = host:accept()
while true do
  user:settimeout(10) --- timeout de 10 segundos, se ninguem escrever nd em 10 segundos o server manda uma mensagem pro client
  local msg,stat = user:receive()
  if stat == 'closed' then -- verificar se a conexão foi fechada
     break
  end
  if msg and stat ~= 'timeout' then
     print(msg)
  else
     user:send('RESPON DE AI KRA!\n')
  end
end

 

Client:

require('socket') -- sempre o require
local client = socket.connect('localhost',1234)
if client then
   print('Conectado')
else 
   print('offline')
   os.exit()
end
print('Escreva algo')
repeat
   client:send(io.read()..'\n')
   client:settimeout(0.1)
   local msg,stat = client:receive()
   if msg then
    print('MSG DO SERVER:',msg)
   end
until not client

Ai vc pode conversar sozinho com um serer sem ninguem pois do jeito que ele esta só aceita um xDD

 

Agora uma coisa você deve saber:

Para o client

Quando vc usa:

local data = socket.connect...

Esse valor data é a conexão entre vc e o servidor

Para o server

Quando vc usa:

local data = socket.bind...

Esse valor data é sua conexao aberta!

E quando usa:

local user = data:accept()

A variavel user é a conexão entre vc e o client!

Agora vamos fazer um host de chat que comporta mais pessoas

 

require('socket')
--Funçoes
function enviarParaTodos(msg,ig)
  for id,user in pairs(users_list) do 
       if id ~= ig then
           user:send(msg..'\n') -- eu coloquei o \n concanetado no final
       end
  end
end
--
local data = socket.bind('*',7171) -- vamos usar a porta 7171
local users_list = {}
local id = 1
function iniciar()
 while true do
     data:settimeout(0.1)
     local user = data:accept()
     if user then
          local ip = user:getpeername()
          enviarParaTodos(ip..' entrou no chat\m')
          users_list[id] = user
          id = id+1
     end
     for id,user in pairs(users_list) do
          user:settimeout(0.01)
          local msg,stat = user:receive()
          if stat == 'closed' then
             local ip = user:getpeername()
             enviarParaTodos(ip..' saiu',id)
             users_list[id] = nil
          else 
             local ip = user:getpeername()
             print(ip..' enviou: '..msg)
             enviarParaTodos(ip..' enviou: '..msg,id)
          end
     end
 end
end
iniciar()

Esse client:

require('socket') -- sempre o require
local client = socket.connect('localhost',1234)
if client then
   print('Conectado')
else 
   print('offline')
   os.exit()
end
print('Escreva algo')
repeat
   local m = io.read()
   if m ~= '' then
   client:send(m..'\n')
   end
   client:settimeout(0.1)
   local msg,stat = client:receive()
   if msg then
    print(msg)
   end
until not client

Ai vc pode reparar no que eu fiz

Ele verifica se alguem entrou, se tiver entrado ele adciona na tabela.

em seguida ele roda um for para todos que estao na tabela.

é assim que se faz.

 

Como na nossa interface lua nos so podemos usar o io.read para enviar mensagens entao para ver se alguem te enviou algo vc tem que enviar apertar enter para o io.read ter o que retornar para o resto do script continuar, ou entao basta escrever algo.

 

E por utimo. Quando quiser finalizar uma conexao, tanto do host como do client basta usar:

client:close()

 

 

 

Chegamos ao fim de nosso tutorial. eu irei fazer um mini-chat em lua com interface para mostrar como que se faz.

Editado por Mickfern

Compartilhar este post


Link para o post
pejuge2    1
pejuge2

MUITO DOIDA ESSA PARADA.

 

Vlw ursola, adicionei nos favoritos pra estudar mais tarde... Muito bom tuto.

Compartilhar este post


Link para o post
Dartier    0
Dartier

valeu vei, já to fazendo meu chat com socket. ;d

Compartilhar este post


Link para o post
Binicius    0
Binicius

Muito massa"

Compartilhar este post


Link para o post
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  
  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×