Networking using UDP

This is going to be a very brief introduction to LuaSocket, a generic networking library for Lua. In particular, we will be looking at UDP (User Datagram Protocol). UDP is different than TCP in a number of ways. Generally speaking, UDP is simpler and more lightweight.

In this tutorial, we are going to setup a server and a client script. This will allow us to run two or more instances of the engine and pass messages between them. Before we can do that, we first include the LuaSocket module.

socket = require ( "socket" )

Server

The server script creates a UDP object at port 14285. By setting its address to "*" the server will be able to communicate with multiple clients. The server's "update" function iterates incoming messages (datagrams) and logs them. The "log_msg" and "redraw_log" functions are not relevant to LuaSocket and have been added just so we can read the log on-screen.
udp = socket.udp ( )
udp:settimeout ( 0 )
-- bind UDP to all local interfaces 
udp:setsockname ( "*", 14285 )

log_msg ( "Waiting for clients..." )

function update ( )
  -- receive incoming data from clients
  while true do
    local data, ip, port = udp:receivefrom ( )
    if data == nil then
      break
    end
    local sz = string.format ( "Received: %s (%s:%s)", data, ip, port )
    log_msg ( sz )
  end
end

timer = Timer ( )
timer:start ( 100, true )
timer.on_tick = function ( timer )
  update ( )
  redraw_log ( )
end

Client

The client script looks a bit different than the server. Instead of "setsockname", we are using "setpeername" in order to connect with "localhost" at port 14285. Assuming the UDP object has connected successfully, we then send a "Hello" message to the server.
udp = socket.udp ( )
udp:settimeout ( 0 )
-- connect to UDP server
udp:setpeername ( "localhost", 14285 )

udp:send ( "Hello" )

keyboard.on_press = function ( keyboard, key )
  -- send the pressed key number to server
  udp:send ( key )
end

Notice that we have added a callback function that sends a message to the server whenever a keyboard key is pressed. This is just for illustrative purposes and is far from ideal since the client can mash the keys at a rather high rate. Usually, it is best to keep the volume of server and client(s) communication to a minimum.

Receiving and sending datagrams

There are a few other UDP functions that were not shown in this tutorial. For example, once the client has connected to a server via "setpeername", he receives data exclusively from that server using "receive" (instead of "receivefrom"). This is done in loop because there could be several queued datagrams:

  while true do
    local data = udp:receive ( )
    if data == nil then
      break
    end
  end

Since the server could be communicating with several clients, it's important to note the "sendto" function. It is similar to "send" except that "sendto" requires the explicit IP address and port of the receiving client.

  udp:sendto ( data, ip, port )
Download:  server.lua
client.lua