UPDATE:
 I did find the code above to be blocking, meaning I couldn’t do anything WHILE running = true. I modified the code a bit to work for what I need. There is only one file, both server and client. Load the app on two devices. Enter the other device info into the textboxes and you will be able to control the other device’s ball.Â
local socket = require(“socket”)
local widget= require (“widget”)
local client= socket.connect(“www.google.com”, 80)
local ip, port = client:getsockname()
  udp=socket.udp()
  udp:settimeout(0)
  udp:setsockname(ip, port)
  local data
ipp = display.newText("IP = "…ip, 10, 10, native.systemFont, 10)
portt = display.newText("PORT = "…port, 10, 20, native.systemFont, 10)
sendIP=native.newTextField(10, 40, 200, 40)
sendPORT=native.newTextField(10, 85, 200, 40)
sendIP.text=ip
sendPORT.text=port
function ButEvent(e)
  if (e.phase==“began”) and (sendIP.text~="") then
  udpp=socket.udp()
  udpp:settimeout(0)
  udpp:setpeername(sendIP.text, tonumber(sendPORT.text))
  local dg = e.target.id
  local snd = udpp:send(dg)
  end
end
upBut=widget.newButton{
left=100,
top=160,
width=55,
height=25,
label=“Up”,
id=“up”,
onEvent=ButEvent,
}
ball = widget.newButton{
  left=100,
top=260,
width=25,
height=25,
id=“ball”,Â
}
downBut=widget.newButton{
left=100,
top=360,
width=55,
height=25,
label=“Down”,
id=“down”,
onEvent=ButEvent,
}
leftBut=widget.newButton{
left=10,
top=260,
width=55,
height=25,
label=“left”,
id=“left”,
onEvent=ButEvent,
}
rightBut=widget.newButton{
left=200,
top=260,
width=55,
height=25,
label=“Right”,
id=“right”,
onEvent=ButEvent,
}
local function receiveUdpMsg(e)
  print(“R”)
    data = udp:receive()
    if data ~= nil then
      if (data==“up”)then ball.y=ball.y-10
        print(“up”)
      elseif (data==“down”) then ball.y=ball.y+10
        print(“Down”)
      elseif (data==“left”) then ball.x=ball.x-10
        print(“left”)
      elseif (data==“right”) then ball.x=ball.x+10
        print(“Right”)
      end
    end
    socket.sleep(0.01)
   recv= timer.performWithDelay(100, receiveUdpMsg)
end
recv= timer.performWithDelay(100, receiveUdpMsg)
Chris Rennie