Local Multiplayer with UDP/TCP

@Mark

Yea I’ve copied the exact code posted above. Hmm… So the continuous loop occurs means that my devices are still not connected to each other? Are there any working examples out here which I can refer to?

Thanks!

Actually, if the other device is getting the message they are connected. What I think is happening is that you are connecting more than once.

From the code above, my best guess is that it is because you are using a “tap” listener and holding the button down. If you use a “touch” listener and make it connect on release then it should only connect once.

Scott,

I guess this is because you are trying to create the server twice with the same IP

Replace line 162 (server.createServer) with the following:


local serverc = display.newText(“Create server”, 400, 110, “pixelDR”, 36)

serverc:setTextColor(255, 255, 0)

servercF = function(event)

    server.createServer()

end

serverc:addEventListener(“tap”,servercF)


Then “create server” in just one of the simulators

Try using the code, provided in this thread and change it when you have it working properly

Best of luck,

I tried this demo on two separate versions of corona to try to test this code it works fine on one simulator but when is try to have two simulators open the code i get this error "

File: server.lua

Line: 22

Attempt to index local ‘tcp’ (a nil value)"

stack traceback:

server.lua:22: in function ‘createServer’

main.lua:161: in main chunk"

here is my code

--main.lua local socket = require("socket") local server = require("server") server\_ip = 0 local getClientIP local findServer local connectToServer local createClientLoop getClientIP = function() local s = socket.udp() --creates a UDP object s:setpeername( "74.125.115.104", 80 ) --Google website local ip, sock = s:getsockname() print( "Client IP / socket:", ip, sock ) return ip end findServer = function() local newServers = {} local msg = "AwesomeGameServer" local listen = socket.udp() listen:setsockname( "226.192.1.1", 1234 ) --this only works if the device supports multicast local name = listen:getsockname() if ( name ) then --test to see if device supports multicast listen:setoption( "ip-add-membership", { multiaddr="226.192.1.1", interface = getClientIP() } ) else --the device doesn't support multicast so we'll listen for broadcast listen:close() --first we close the old socket; this is important listen = socket.udp() --make a new socket listen:setsockname( getClientIP(), 1234 ) --set the socket name to the real IP address end listen:settimeout( 0 ) --move along if there is nothing to hear local stop local counter = 0 --pulse counter local function look() repeat local data, ip, port = listen:receivefrom() --print( "data: ", data, "IP: ", ip, "port: ", port ) if data and data == msg then if not newServers[ip] then print( "Client hears a server at IP " .. ip .. " and port " .. port ) local params = { ["ip"]=ip, ["port"]=1235 } newServers[ip] = params server\_ip = ip end end until not data counter = counter + 1 if counter == 20 then --stop after 2 seconds stop() end end --pulse 10 times per second local beginLooking = timer.performWithDelay( 100, look, 0 ) function stop() timer.cancel( beginLooking ) --evaluateServerList( newServers ) --do something with your found servers listen:close() --never forget to close the socket! end end connectToServer = function( ip, port ) print("Sending message to IP " .. ip .. " and port " .. port) local sock, err = socket.connect( ip, port ) if sock == nil then return false end sock:settimeout( 0 ) sock:setoption( "tcp-nodelay", true ) --disable Nagle's algorithm sock:send("CLIENT " ..ip .. " " .. port .. "\n") return sock end createClientLoop = function( sock, ip, port ) local buffer = {} local clientPulse local function cPulse() local allData = {} local data, err -- Get line by line of data and store in allData repeat data, err = sock:receive() if data then allData[#allData+1] = data end if ( err == "closed" and clientPulse ) then --try again if connection closed print("Client connection closed. Re-connect and try to receive again.") connectToServer( ip, port ) data, err = sock:receive() if data then allData[#allData+1] = data end end until not data if ( #allData \> 0 ) then for i, thisData in ipairs( allData ) do print( "Client received from server:", thisData ) --------------------------- --react to incoming data --------------------------- end end -- TO DO: set a buffer to send, depending on action for i, msg in pairs( buffer ) do local data, err = sock:send(msg) if ( err == "closed" and clientPulse ) then --try to reconnect and resend print("Client connection closed. Re-connect and try to send again.") connectToServer( ip, port ) data, err = sock:send( msg ) end end end --pulse 10 times per second clientPulse = timer.performWithDelay( 100, cPulse, 0 ) local function stopClient() timer.cancel( clientPulse ) --cancel timer clientPulse = nil sock:close() end return stopClient end ------------------------------------------------------------------------------------ ----------------------- server.createServer() ----------------------- -- server\_b local serverb = display.newText("Advertise server", display.contentCenterX, display.contentCenterY-100, nil, 36) serverb:setTextColor(255, 0, 0) -- Advertise the server ----------------------------- serverbF = function(event) server.advertiseServer() end ----------------------------- serverb:addEventListener("tap",serverbF) -- client\_b local clientb = display.newText("Get client IP", display.contentCenterX, display.contentCenterY-50, nil, 36) clientb:setTextColor(0, 255, 0) -- Client finds out its IP address ----------------------- clientbF = function(event) findServer() end ----------------------- clientb:addEventListener("tap",clientbF) -- send\_b local sendb = display.newText("Connect to Server", display.contentCenterX, display.contentCenterY, nil, 36) sendb:setTextColor(255, 0, 255) -- Connect to server ----------------------- sendbF = function(event) -- Get a session ID ("sock") from server local sock = connectToServer(server\_ip,1235) createClientLoop(sock,server\_ip,1235) end ----------------------- sendb:addEventListener("tap",sendbF)

--server.lua local S = {} local socket = require( "socket" ) local clientList = {} local clientBuffer = {} local tableTest= {} tableTest[1]= "hi\n" S.getServerIP = function() local s = socket.udp() s:setpeername( "74.125.115.104", 80 ) local ip, sock = s:getsockname() print( "Server IP / socket:", ip, sock ) return ip end S.createServer = function() local tcp, err = socket.bind( S.getServerIP(), 1235 ) --create a server object tcp:settimeout( 0 ) local function sPulse() ------------------------------------------------------ -- Check for available clients ------------------------------------------------------ repeat local client = tcp:accept() --allow a new client to connect if client then print( "Server detected a client" ) client:settimeout( 0 ) --just check the socket and keep going --TO DO: implement a way to check to see if the client has connected previously --consider assigning the client a session ID and use it on reconnect. clientList[#clientList+1] = client -- TO DO clientBuffer[client] = { tableTest[1] } --just including something to send below end until not client -- Check to see which client connections are available local ready, writeReady, err = socket.select( clientList, clientList, 0 ) ------------------------------------------------------- -- Look for data from clients ------------------------------------------------------- if err == nil then for i = 1, #ready do --list of clients who are available local client = ready[i] local allData = {} --this holds all lines from a given client -- From current client, get line by line of data and store in allData repeat local data, err = client:receive() -- get a line of data from the client, if any if data then allData[#allData+1] = data end until not data if ( #allData \> 0 ) then --figure out what the client said to the server -- Get each line from allData for i, thisData in ipairs( allData ) do print( "Server received from client:", thisData ) --------------------- -- Do stuff with data --------------------- end end end ------------------------------------------------------ -- Send whatever is in the server's buffer ------------------------------------------------------ for sock, buffer in pairs( clientBuffer ) do -- Grab each line from the buffer meant for current client, and send it for \_, msg in pairs( buffer ) do --might be empty print("Server sends to clients:", msg) local data, err = sock:send( msg ) --send the message to the clients print("Err: ",err) print("\n") end end end end -- Call above function every 100 ms local serverPulse = timer.performWithDelay( 100, sPulse, 0 ) local function stopServer() timer.cancel( serverPulse ) --cancel timer tcp:close() for i, v in pairs( clientList ) do v:close() end end return stopServer end S.advertiseServer = function() print("Advertise server") local send = socket.udp() send:settimeout( 0 ) --this is important (how long to wait before moving on) local stop local counter = 0 --using this, we can advertise our IP address for a limited time local function broadcast() local msg = "AwesomeGameServer" --multicast IP range from 224.0.0.0 to 239.255.255.255 send:sendto( msg, "226.192.1.1", 1234 ) --not all devices can multicast so it's a good idea to broadcast too --however, for broadcast to work, the network has to allow it send:setoption( "broadcast", true ) --turn on broadcast send:sendto( msg, "255.255.255.255", 1234 ) send:setoption( "broadcast", false ) --turn off broadcast counter = counter + 1 if ( counter == 80 ) then --stop after 8 seconds stop() -- variable to a function end end --pulse 10 times per second local serverBroadcast = timer.performWithDelay( 100, broadcast, 0 ) stop = function() timer.cancel( serverBroadcast ) --cancel timer stop = nil print("Stop server broadcast") end end return S

thanks,

Scott

  when I click the button to send , the “false” message appears on console. I think that this is not connecting , what could it be?

I may be you need \n the text at the end. Some sample code might be helpful.
P.s
If your interested in local multiplayer Check this link out
https://forums.coronalabs.com/topic/58394-got-old-auto-lan-to-work/#entry302111

My turn to hit the wall trying this out…

My test app code is in main.lua and the p2p support code is in a file called n.lua.

The code in n.lua is more or less copied from the examples above. I haven’t gotten further than just trying to start/advertise the server and then recognize it, and this works very well on the simulator:

The app recognizes and lists it’s own server just fine. Also. if I run the app on a device on the same network, the app in the simulator sees the server on the device perfectly.

But no matter what I do I cannot make the app running on a device see any other server. Not the

server running on the same app, not a server running on any other device and not any server running on the simulated app. I just don’t know how to procede from here. I have no clue as to why this is so.

I would be quite grateful if anybody could help me as I’m a bit desperate at this point… The code are as follows:

main.lua:

n = require("n") print("\n\nStarting P2P Test\n") \_W = display.contentWidth \_H = display.contentHeight \_CENTER\_X = display.contentCenterX \_CENTER\_Y = display.contentCenterY \_FULL\_W = display.actualContentWidth \_FULL\_H = display.actualContentHeight local serverNameTE = nil local serverButton = nil local serverButtonText = nil local clientButton = nil local clientButtonText = nil local serverListST = nil local broadcasting = false local looking = false local clearEditFont = native.newFont(native.systemFont, 36) local stopServAdvFunc = nil local stoppedServAdvFunc = nil for i=10, 1, -1 do print(i) end local clientList = {} local clientBuffer = {} print("Creating server...") local server = n.createServer(clientList, clientBuffer) local evaluateServerList = function( newServers ) -- Do something with your found servers -- Server search finished looking = false clientButtonText.text = "Look for server" serverListST.text = "Server list:" -- Show result local servNum = 0 for key,value in pairs(newServers) do print("\n") servNum = servNum + 1 print("Server: " .. newServers[key]["name"] .. ", " .. newServers[key]["ip"]) serverListST.text = serverListST.text .. "\n" .. newServers[key]["name"] .. ", " .. newServers[key]["ip"] end if (servNum == 0) then print("No servers found") end end local function stoppedServAdvFunc() serverButtonText.text = "Advertise server" broadcasting = false print("Server broadcasting stopped by timer") end local function serverButtonHandler(e) if (e.phase == "ended") then if (broadcasting == true and stopServAdvFunc ~= nil) then broadcasting = false serverButtonText.text = "Advertise server" stopServAdvFunc() else broadcasting = true serverButtonText.text = "Stop advertizing server" stopServAdvFunc = n.advertiseServer(serverNameTE.text, stoppedServAdvFunc) end end end serverNameTE = native.newTextField(\_W/2, 100, \_W\*0.8, 50) serverNameTE.font = clearEditFont serverNameTE.height = nil serverNameTE:resizeHeightToFitFont() serverButton = display.newRect(\_W/2, 200, 500, 60) serverButtonText = display.newText("Advertise server", \_W/2, 200) serverButtonText:setFillColor(0) serverButton:addEventListener("touch", serverButtonHandler) serverButton.stoppedBoadcasting = function() print("S T O P") serverButtonText.text = "Advertise server" end local function clientButtonHandler(e) if (e.phase == "ended") then if (looking == true and clientButton.stopLooking ~= nil) then looking = false clientButtonText.text = "Look for server" clientButton.stopLooking() else looking = true clientButtonText.text = "Looking for server..." -- n.advertiseServer(serverButton) n.findServer(clientButton, evaluateServerList) end end end clientButton = display.newRect(\_W/2, 400, 500, 60) clientButtonText = display.newText("Look for server", \_W/2, 400) clientButtonText:setFillColor(0) clientButton:addEventListener("touch", clientButtonHandler) serverListST = display.newText("Server list:", \_W/2, \_H\*0.4, \_W\*0.8, \_H/2, native.systemFont, 32) serverListST.anchorY = 0

n.lua:

local n = {} print( "n.lua has been loaded." ) local socket = require("socket") n.getIP = function() local s = socket.udp() -- Creates a UDP object s:setpeername("74.125.115.104", 80) -- Any IP address will do local ip, sock = s:getsockname() print( "myIP:", ip, sock ) return ip end n.createServer = function(clientList, clientBuffer) local tcp, err = socket.bind( n.getIP(), 22222 ) -- Create a server object tcp:settimeout( 0 ) local function sPulse() repeat local client = tcp:accept() -- Allow a new client to connect if client then print( "Found client" ) client:settimeout( 0 ) -- Just check the socket and keep going -- TO DO: implement a way to check to see if the client has connected previously -- Consider assigning the client a session ID and use it on reconnect. clientList[#clientList+1] = client clientBuffer[client] = { "hello\_client\n" } -- Just including something to send below end until not client local ready, writeReady, err = socket.select( clientList, clientList, 0 ) if err == nil then for i = 1, #ready do -- List of clients who are available local client = ready[i] local allData = {} -- This holds all lines from a given client repeat local data, err = client:receive() -- Get a line of data from the client, if any if data then allData[#allData+1] = data end until not data if ( #allData \> 0 ) then -- Figure out what the client said to the server for i, thisData in ipairs( allData ) do print( "thisData: ", thisData ) -- Do stuff with data -- Call callback function? end end end for sock, buffer in pairs( clientBuffer ) do for \_, msg in pairs( buffer ) do -- Might be empty local data, err = sock:send( msg ) -- Send the message to the client end end end end -- Pulse 10 times per second local serverPulse = timer.performWithDelay( 100, sPulse, 0 ) local function stopServer() timer.cancel( serverPulse ) -- Cancel timer tcp:close() for i, v in pairs( clientList ) do v:close() end end return stopServer end n.advertiseServer = function(userNameIn, stoppedBroadcasting) print("advertiseServer(" .. system.getInfo("appName") .. "Server" .. ")") local send = socket.udp() send:settimeout( 0 ) -- This is important (see notes below) local counter = 0 -- Using this, we can advertise our IP address for a limited time local stopBroadcasting local function broadcast() local msg = system.getInfo("appName") .. "Server\n" .. userNameIn -- Multicast IP range from 224.0.0.0 to 239.255.255.255 send:sendto(msg, "228.192.1.1", 11111) -- Not all devices can multicast so it's a good idea to broadcast too -- however, for broadcast to work, the network has to allow it send:setoption( "broadcast", true ) -- Turn on broadcast send:sendto( msg, "255.255.255.255", 11111) send:setoption( "broadcast", false ) -- Turn off broadcast counter = counter + 1 -- print("Broadcasting attempt #" .. counter) if ( counter == 80 ) then -- Stop after 8 seconds stopBroadcasting() end end -- Pulse 10 times per second local serverBroadcast = timer.performWithDelay( 100, broadcast, 0 ) stopBroadcasting = function() -- print("Stopping broadcasting") timer.cancel( serverBroadcast ) -- Cancel timer stoppedBroadcasting() end return stopBroadcasting end n.findServer = function(button, evaluateServerList) print("findServer() - START") local beginLooking local newServers = {} local searchServerName = system.getInfo("appName") .. "Server" print("Searching for servers with id: '" .. searchServerName .. "'") local listen = socket.udp() -- Should it be 228.192.1.1 ??? listen:setsockname( "226.192.1.1", 11111 ) -- This only works if the device supports multicast local name = listen:getsockname() if ( name ) then -- Test to see if device supports multicast listen:setoption( "ip-add-membership", { multiaddr="226.192.1.1", interface = n.getIP() } ) else -- The device doesn't support multicast so we'll listen for broadcast listen:close() -- First we close the old socket; this is important listen = socket.udp() -- Make a new socket listen:setsockname( n.getIP(), 11111 ) -- Set the socket name to the real IP address end listen:settimeout( 0 ) -- Move along if there is nothing to hear local counter = 0 -- Pulse counter -- Stop function local function stop() timer.cancel( beginLooking ) button.stopLooking = nil evaluateServerList( newServers ) -- Do something with your found servers listen:close() -- Never forget to close the socket! end -- Look function local function look() repeat local data, ip, port = listen:receivefrom() if (data) then -- Extract server id (App name) and name from data local serverId = data local serverName = data local idx = string.find(data, "\n") if (idx ~= nil) then serverId = data:sub(1, idx-1) serverName = data:sub(idx+1) end if (serverId == searchServerName) then if not newServers[ip] then print( "I hear a server:", ip, port ) local params = { ["name"]=serverName, ["ip"]=ip, ["port"]=22222 } print("Adding server: " .. data, ip) newServers[ip] = params end end end until not data counter = counter + 1 if counter == 20 then -- Stop after 2 seconds stop() end end -- Pulse 10 times per second beginLooking = timer.performWithDelay( 100, look, 0 ) button.stopLooking = stopLooking print("findServer() - END\n") end n.connectToServer = function( ip, port ) local sock, err = socket.connect( ip, port ) if sock == nil then return false end sock:settimeout( 0 ) sock:setoption( "tcp-nodelay", true ) -- Disable Nagle's algorithm sock:send( "we are connected\n" ) return sock end return n

Is your network preventing the devices from communicating? In many cases, the default setting for a router is to prevent devices from communicating.

Maybe… but isn’t it strange then, that it seems to be a one way blocking?

Scott,

I guess this is because you are trying to create the server twice with the same IP

Replace line 162 (server.createServer) with the following:


local serverc = display.newText(“Create server”, 400, 110, “pixelDR”, 36)

serverc:setTextColor(255, 255, 0)

servercF = function(event)

    server.createServer()

end

serverc:addEventListener(“tap”,servercF)


Then “create server” in just one of the simulators

Try using the code, provided in this thread and change it when you have it working properly

Best of luck,

  when I click the button to send , the “false” message appears on console. I think that this is not connecting , what could it be?

I may be you need \n the text at the end. Some sample code might be helpful.
P.s
If your interested in local multiplayer Check this link out
https://forums.coronalabs.com/topic/58394-got-old-auto-lan-to-work/#entry302111

My turn to hit the wall trying this out…

My test app code is in main.lua and the p2p support code is in a file called n.lua.

The code in n.lua is more or less copied from the examples above. I haven’t gotten further than just trying to start/advertise the server and then recognize it, and this works very well on the simulator:

The app recognizes and lists it’s own server just fine. Also. if I run the app on a device on the same network, the app in the simulator sees the server on the device perfectly.

But no matter what I do I cannot make the app running on a device see any other server. Not the

server running on the same app, not a server running on any other device and not any server running on the simulated app. I just don’t know how to procede from here. I have no clue as to why this is so.

I would be quite grateful if anybody could help me as I’m a bit desperate at this point… The code are as follows:

main.lua:

n = require("n") print("\n\nStarting P2P Test\n") \_W = display.contentWidth \_H = display.contentHeight \_CENTER\_X = display.contentCenterX \_CENTER\_Y = display.contentCenterY \_FULL\_W = display.actualContentWidth \_FULL\_H = display.actualContentHeight local serverNameTE = nil local serverButton = nil local serverButtonText = nil local clientButton = nil local clientButtonText = nil local serverListST = nil local broadcasting = false local looking = false local clearEditFont = native.newFont(native.systemFont, 36) local stopServAdvFunc = nil local stoppedServAdvFunc = nil for i=10, 1, -1 do print(i) end local clientList = {} local clientBuffer = {} print("Creating server...") local server = n.createServer(clientList, clientBuffer) local evaluateServerList = function( newServers ) -- Do something with your found servers -- Server search finished looking = false clientButtonText.text = "Look for server" serverListST.text = "Server list:" -- Show result local servNum = 0 for key,value in pairs(newServers) do print("\n") servNum = servNum + 1 print("Server: " .. newServers[key]["name"] .. ", " .. newServers[key]["ip"]) serverListST.text = serverListST.text .. "\n" .. newServers[key]["name"] .. ", " .. newServers[key]["ip"] end if (servNum == 0) then print("No servers found") end end local function stoppedServAdvFunc() serverButtonText.text = "Advertise server" broadcasting = false print("Server broadcasting stopped by timer") end local function serverButtonHandler(e) if (e.phase == "ended") then if (broadcasting == true and stopServAdvFunc ~= nil) then broadcasting = false serverButtonText.text = "Advertise server" stopServAdvFunc() else broadcasting = true serverButtonText.text = "Stop advertizing server" stopServAdvFunc = n.advertiseServer(serverNameTE.text, stoppedServAdvFunc) end end end serverNameTE = native.newTextField(\_W/2, 100, \_W\*0.8, 50) serverNameTE.font = clearEditFont serverNameTE.height = nil serverNameTE:resizeHeightToFitFont() serverButton = display.newRect(\_W/2, 200, 500, 60) serverButtonText = display.newText("Advertise server", \_W/2, 200) serverButtonText:setFillColor(0) serverButton:addEventListener("touch", serverButtonHandler) serverButton.stoppedBoadcasting = function() print("S T O P") serverButtonText.text = "Advertise server" end local function clientButtonHandler(e) if (e.phase == "ended") then if (looking == true and clientButton.stopLooking ~= nil) then looking = false clientButtonText.text = "Look for server" clientButton.stopLooking() else looking = true clientButtonText.text = "Looking for server..." -- n.advertiseServer(serverButton) n.findServer(clientButton, evaluateServerList) end end end clientButton = display.newRect(\_W/2, 400, 500, 60) clientButtonText = display.newText("Look for server", \_W/2, 400) clientButtonText:setFillColor(0) clientButton:addEventListener("touch", clientButtonHandler) serverListST = display.newText("Server list:", \_W/2, \_H\*0.4, \_W\*0.8, \_H/2, native.systemFont, 32) serverListST.anchorY = 0

n.lua:

local n = {} print( "n.lua has been loaded." ) local socket = require("socket") n.getIP = function() local s = socket.udp() -- Creates a UDP object s:setpeername("74.125.115.104", 80) -- Any IP address will do local ip, sock = s:getsockname() print( "myIP:", ip, sock ) return ip end n.createServer = function(clientList, clientBuffer) local tcp, err = socket.bind( n.getIP(), 22222 ) -- Create a server object tcp:settimeout( 0 ) local function sPulse() repeat local client = tcp:accept() -- Allow a new client to connect if client then print( "Found client" ) client:settimeout( 0 ) -- Just check the socket and keep going -- TO DO: implement a way to check to see if the client has connected previously -- Consider assigning the client a session ID and use it on reconnect. clientList[#clientList+1] = client clientBuffer[client] = { "hello\_client\n" } -- Just including something to send below end until not client local ready, writeReady, err = socket.select( clientList, clientList, 0 ) if err == nil then for i = 1, #ready do -- List of clients who are available local client = ready[i] local allData = {} -- This holds all lines from a given client repeat local data, err = client:receive() -- Get a line of data from the client, if any if data then allData[#allData+1] = data end until not data if ( #allData \> 0 ) then -- Figure out what the client said to the server for i, thisData in ipairs( allData ) do print( "thisData: ", thisData ) -- Do stuff with data -- Call callback function? end end end for sock, buffer in pairs( clientBuffer ) do for \_, msg in pairs( buffer ) do -- Might be empty local data, err = sock:send( msg ) -- Send the message to the client end end end end -- Pulse 10 times per second local serverPulse = timer.performWithDelay( 100, sPulse, 0 ) local function stopServer() timer.cancel( serverPulse ) -- Cancel timer tcp:close() for i, v in pairs( clientList ) do v:close() end end return stopServer end n.advertiseServer = function(userNameIn, stoppedBroadcasting) print("advertiseServer(" .. system.getInfo("appName") .. "Server" .. ")") local send = socket.udp() send:settimeout( 0 ) -- This is important (see notes below) local counter = 0 -- Using this, we can advertise our IP address for a limited time local stopBroadcasting local function broadcast() local msg = system.getInfo("appName") .. "Server\n" .. userNameIn -- Multicast IP range from 224.0.0.0 to 239.255.255.255 send:sendto(msg, "228.192.1.1", 11111) -- Not all devices can multicast so it's a good idea to broadcast too -- however, for broadcast to work, the network has to allow it send:setoption( "broadcast", true ) -- Turn on broadcast send:sendto( msg, "255.255.255.255", 11111) send:setoption( "broadcast", false ) -- Turn off broadcast counter = counter + 1 -- print("Broadcasting attempt #" .. counter) if ( counter == 80 ) then -- Stop after 8 seconds stopBroadcasting() end end -- Pulse 10 times per second local serverBroadcast = timer.performWithDelay( 100, broadcast, 0 ) stopBroadcasting = function() -- print("Stopping broadcasting") timer.cancel( serverBroadcast ) -- Cancel timer stoppedBroadcasting() end return stopBroadcasting end n.findServer = function(button, evaluateServerList) print("findServer() - START") local beginLooking local newServers = {} local searchServerName = system.getInfo("appName") .. "Server" print("Searching for servers with id: '" .. searchServerName .. "'") local listen = socket.udp() -- Should it be 228.192.1.1 ??? listen:setsockname( "226.192.1.1", 11111 ) -- This only works if the device supports multicast local name = listen:getsockname() if ( name ) then -- Test to see if device supports multicast listen:setoption( "ip-add-membership", { multiaddr="226.192.1.1", interface = n.getIP() } ) else -- The device doesn't support multicast so we'll listen for broadcast listen:close() -- First we close the old socket; this is important listen = socket.udp() -- Make a new socket listen:setsockname( n.getIP(), 11111 ) -- Set the socket name to the real IP address end listen:settimeout( 0 ) -- Move along if there is nothing to hear local counter = 0 -- Pulse counter -- Stop function local function stop() timer.cancel( beginLooking ) button.stopLooking = nil evaluateServerList( newServers ) -- Do something with your found servers listen:close() -- Never forget to close the socket! end -- Look function local function look() repeat local data, ip, port = listen:receivefrom() if (data) then -- Extract server id (App name) and name from data local serverId = data local serverName = data local idx = string.find(data, "\n") if (idx ~= nil) then serverId = data:sub(1, idx-1) serverName = data:sub(idx+1) end if (serverId == searchServerName) then if not newServers[ip] then print( "I hear a server:", ip, port ) local params = { ["name"]=serverName, ["ip"]=ip, ["port"]=22222 } print("Adding server: " .. data, ip) newServers[ip] = params end end end until not data counter = counter + 1 if counter == 20 then -- Stop after 2 seconds stop() end end -- Pulse 10 times per second beginLooking = timer.performWithDelay( 100, look, 0 ) button.stopLooking = stopLooking print("findServer() - END\n") end n.connectToServer = function( ip, port ) local sock, err = socket.connect( ip, port ) if sock == nil then return false end sock:settimeout( 0 ) sock:setoption( "tcp-nodelay", true ) -- Disable Nagle's algorithm sock:send( "we are connected\n" ) return sock end return n

Is your network preventing the devices from communicating? In many cases, the default setting for a router is to prevent devices from communicating.

Maybe… but isn’t it strange then, that it seems to be a one way blocking?

Hi,
 
I am facing a different kind of issue in createClientLoop method. For the first time my server is sending msg to client and client is sending msg to server in method connectToServer. I am triggering createClientLoop  inside connectToServer but sock is giving me timeout error in method createClientLoop. Please help me.
 
[lua]connectToServer = function( ip, port )
 
    local sock, err = socket.connect( ip, port )
    if sock == nil then
        return false
    end    
 
    sock:settimeout( 0 )
    sock:setoption( “tcp-nodelay”, true )  --disable Nagle’s algorithm
    sock:send(“Hi Server”…"\n")
    createClientLoop(sock,ip, port)
    return sock
end
 

createClientLoop = function( sock, ip, port )
 
    local buffer = {}
    local clientPulse
 
    local function cPulse()
        – local allData = {}
        local data, err
        repeat
 
            data, err = sock:receive()
            if data then
                print( “recvd data” )
                allData[#allData+1] = data
            else
                print( 'err: '…err ) – HERE I AM GETTING TIMEOUT ERROR
            end
            if ( err == “closed” and clientPulse ) then  --try again if connection closed
                C.connectToServer( ip, port )
                data, err = sock:receive()
                if data then
                    allData[#allData+1] = data
                end
            end
        until not data
 
        – if ( #allData > 0 ) then
        –     for i, thisData in ipairs( allData ) do
        –         print( "thisData: ", thisData )
        –         --react to incoming data 
        –     end
        – end
 
        – for i, msg in pairs( buffer ) do
        –     local data, err = sock:send(msg)
        –     if ( err == “closed” and clientPulse ) then  --try to reconnect and resend
        –         connectToServer( ip, port )
        –         data, err = sock:send( msg )
        –     end
        – end
    end
 
    --pulse 10 times per second
    clientPulse = timer.performWithDelay( 100, cPulse, 0 )
 
    local function stopClient()
        timer.cancel( clientPulse )  --cancel timer
        clientPulse = nil
        sock:close()
    end
    return stopClient
end[/lua]

Hi,
 
I am facing a different kind of issue in createClientLoop method. For the first time my server is sending msg to client and client is sending msg to server in method connectToServer. I am triggering createClientLoop  inside connectToServer but sock is giving me timeout error in method createClientLoop. Please help me.
 
[lua]connectToServer = function( ip, port )
 
    local sock, err = socket.connect( ip, port )
    if sock == nil then
        return false
    end    
 
    sock:settimeout( 0 )
    sock:setoption( “tcp-nodelay”, true )  --disable Nagle’s algorithm
    sock:send(“Hi Server”…"\n")
    createClientLoop(sock,ip, port)
    return sock
end
 

createClientLoop = function( sock, ip, port )
 
    local buffer = {}
    local clientPulse
 
    local function cPulse()
        – local allData = {}
        local data, err
        repeat
 
            data, err = sock:receive()
            if data then
                print( “recvd data” )
                allData[#allData+1] = data
            else
                print( 'err: '…err ) – HERE I AM GETTING TIMEOUT ERROR
            end
            if ( err == “closed” and clientPulse ) then  --try again if connection closed
                C.connectToServer( ip, port )
                data, err = sock:receive()
                if data then
                    allData[#allData+1] = data
                end
            end
        until not data
 
        – if ( #allData > 0 ) then
        –     for i, thisData in ipairs( allData ) do
        –         print( "thisData: ", thisData )
        –         --react to incoming data 
        –     end
        – end
 
        – for i, msg in pairs( buffer ) do
        –     local data, err = sock:send(msg)
        –     if ( err == “closed” and clientPulse ) then  --try to reconnect and resend
        –         connectToServer( ip, port )
        –         data, err = sock:send( msg )
        –     end
        – end
    end
 
    --pulse 10 times per second
    clientPulse = timer.performWithDelay( 100, cPulse, 0 )
 
    local function stopClient()
        timer.cancel( clientPulse )  --cancel timer
        clientPulse = nil
        sock:close()
    end
    return stopClient
end[/lua]