Shootout Echo

lua-users home
wiki

How to get the posix and socket shared libraries loaded into the Lua interpreter is a local issue.

-- 2003-09 (Lua 5.0)
-- lua -lposix -lsocket echo.lua [number]

data = 'Hello there sailor\n'
dlen = string.len(data)

-- this documents the ways a tcp receive() can go wrong.  it should
-- not be called if the 2nd result of calling receive() == nil, but it
-- guards against the possibility even so.
function socket_receive_error(err)
   if err == nil then
      print'socket_receive_error(): err == nil, oops!'
   elseif err == 'closed' then
      print'<socket>:receive(): connection closed'
      return
   elseif err == 'timeout' then
      print'<socket>:receive(): connection timed out'
   else
      error('<socket>:receive(): error: '..err)
   end
end

function server_sock()
   local server,err = socket.bind('127.0.0.1',0)
   assert(server,err)
   return server
end

function get_port(sock)
   local _,port = sock:getsockname()
   return port
end

function client_sock(port)
   local client,err = socket.connect('127.0.0.1',port)
   assert(client,err)
   return client
end

function echo_client(n,port)
   local s = client_sock(port)
   for i=1,n do
      s:send(data)
      local d,err = s:receive(dlen)
      if err then
         socket_receive_error(err)
         break
      end
      if d ~= data then error('server reply: '..d) end
   end
   s:close()
end

function echo_server(n)
   local ssock = server_sock()
   local pid = posix.fork()
   if pid == 0 then
      echo_client(n,get_port(ssock)) -- child is client
   else
      local n = 0
      local client,err = ssock:accept()
      while true do
         local data,err = client:receive(dlen)
         if err then
            socket_receive_error(err)
            break
         end
         n = n + string.len(data)
         client:send(data)
      end
      print('server received '..n..' bytes')
   end
end

-- insist on a proper argument if one's present, no silent corrections
if arg and arg[1] then
   n = tonumber(arg[1])
   if not n then error('arg must be a number') end
else
   n = 1
end
echo_server(n)

--SteveElkins


RecentChanges · preferences
edit · history
Last edited October 25, 2008 4:50 pm GMT (diff)