Page 1 of 2

Getting local IP address using UDP?

Posted: Wed Apr 06, 2022 4:23 pm
by Yolwoocle
I'm trying to set up a LAN type game, where clients connect to some host in the local network using UDP. Right now I manually type the local IP address (something like 192.168.0.11) I get from "ipconfig" on Windows / "ip a" on Linux, but I would like to automate this process, so that clients can automatically connect to the host (it always has the same known port, finding this isn't an issue).
The folks on the LÖVE Discord server were lovely, but I couldn't really get it working properly. I would really appreciate it if someone could help while keeping it simple, as I don't have a lot of experience with networking. Thanks! :awesome:

Re: Getting local IP address using UDP?

Posted: Wed Apr 06, 2022 6:36 pm
by MrFariator
Perhaps this thread is what you're looking for?
You can create a UDP socket, use setpeername to bind it to any address outside your network, then use getsockname to get the local IP. This should work even if the remote address doesn't actually exist, as long as it gets routed outside your network (so you can use a reserved address, like something in the 240.0.0.1 - 255.255.255.254 range).
I suppose another method is to run the OS-specific ipconfig call with lua's os.execute, then grab and parse the output. Might also be worth checking if any libraries facilitate this behavior.

Generally though, I figure having a manual ip input field might work out best in case the automatic ip detection were to fail somehow.

Re: Getting local IP address using UDP?

Posted: Wed Apr 06, 2022 7:56 pm
by Yolwoocle
MrFariator wrote: Wed Apr 06, 2022 6:36 pm Perhaps this thread is what you're looking for?
You can create a UDP socket, use setpeername to bind it to any address outside your network, then use getsockname to get the local IP. This should work even if the remote address doesn't actually exist, as long as it gets routed outside your network (so you can use a reserved address, like something in the 240.0.0.1 - 255.255.255.254 range).
I suppose another method is to run the OS-specific ipconfig call with lua's os.execute, then grab and parse the output. Might also be worth checking if any libraries facilitate this behavior.

Generally though, I figure having a manual ip input field might work out best in case the automatic ip detection were to fail somehow.
Thanks! I have tried the setpeername trick, but it seemed to always give me localhost or 0.0.0.0. Maybe I'm doing something wrong :P

Code: Select all

udp:setpeername("*")
local ip = udp:getsockname()
About manually entering the IP, I think that this is what I will go for. Right now I have people enter it in a serverip.txt file, but this is kinda clunky. I will have to code text fields one day anyway :P

Re: Getting local IP address using UDP?

Posted: Wed Apr 06, 2022 7:57 pm
by Yolwoocle
Another option would be to ditch the LAN idea and have a known server IP address that everyone connects to. It could be relatively easy to do, most of what this server would do would be to relay info it receives to the host, instead of this info being directly sent to the host. It's kinda like a proxy. I even have a raspberry pi that could do the trick

Re: Getting local IP address using UDP?

Posted: Thu Apr 07, 2022 12:48 am
by pgimeno
This game uses a discovery service:
viewtopic.php?f=14&t=79255

It uses this library:
https://github.com/Germanunkol/Affair

And this software for the server:
https://github.com/Germanunkol/AffairMainServer

The library claims to support serverless LAN discovery using broadcast; I don't know how well that works. Otherwise it can always fall back to using the PHP-based server.

Re: Getting local IP address using UDP?

Posted: Thu Apr 07, 2022 7:06 am
by Yolwoocle
pgimeno wrote: Thu Apr 07, 2022 12:48 am This game uses a discovery service:
viewtopic.php?f=14&t=79255

It uses this library:
https://github.com/Germanunkol/Affair

And this software for the server:
https://github.com/Germanunkol/AffairMainServer

The library claims to support serverless LAN discovery using broadcast; I don't know how well that works. Otherwise it can always fall back to using the PHP-based server.
Thanks a lot, but I really want something simple that I can bundle in a function without having to rework the whole structure of my code. All I'm looking for is to get the local IP address. I'll keep in mind this library for a future project though.

Re: Getting local IP address using UDP?

Posted: Thu Apr 21, 2022 7:36 am
by Yolwoocle
Ok

Re: Getting local IP address using UDP?

Posted: Fri Apr 22, 2022 4:38 pm
by yal2du
Yolwoocle wrote: Wed Apr 06, 2022 4:23 pm ... I get from "ipconfig" on Windows / "ip a" on Linux, but I would like to automate this process ...
Parse the output of ipconfig looking for adapter(s) with a default gateway, then give user those choices to connect.

-- see code next post --

https://stackoverflow.com/questions/132 ... 715#326715

Re: Getting local IP address using UDP?

Posted: Fri Apr 22, 2022 7:29 pm
by yal2du
tested under win10 and lmde5

Code: Select all

do

   
   local function os_capture(cmd, raw)
      local f = assert(io.popen(cmd, 'r'))
      local s = assert(f:read('*a'))
      f:close()
      if raw then return s end
      s = string.gsub(s, '^%s+', '')
      s = string.gsub(s, '%s+$', '')
      s = string.gsub(s, '[\n\r]+', ' ')
      return s
   end


   local oss = love.system.getOS()
   local cmd = "ip a"
   if oss == "Windows" then cmd = "ipconfig" end
   local config = os_capture(cmd,true)
   print("config ", config)


   local function extract_ip_windows(s)
      local s_dg = " Default Gateway . . . . . . . . . :"
      local s_ip = " IPv4 Address. . . . . . . . . . . : "
      local adapters = {}
      local dg_first = false
      local i = 1
      while i < #s do
         local f_dg, f_dge  = string.find(s, s_dg, i, true)
         local f_ip, f_ipe  = string.find(s, s_ip, i, true)
         if (f_dg == nil) or (f_ip == nil) then
            print("no (more) matching config lines found")
            break
         end
         if (i == 1) and (f_ip > f_dg) then dg_first = true end
         local pattern = "(%d+%.%d+%.%d+%.%d+)%c"
         local ip = string.match(s,pattern,f_ipe+1)
         local dg = string.find(s,"%c",f_dge+1)
         if dg > (f_dge+3) then
            print(ip)
            table.insert(adapters,ip)
         end
         if dg_first then i = f_ipe else i = f_dge end
      end
      return adapters
   end


   local function extract_ip_linux(s)
      local s_dg = "link/ether"
      local s_ip = "inet "
      local adapters = {}
      local i = 1
      while i < #s do
         local f_dg, f_dge  = string.find(s, s_dg, i, true)
         if (f_dg == nil) then
            print("no (more) matching config lines found")
            break
         end
         local f_ip, f_ipe  = string.find(s, s_ip, f_dge, true)
         if (f_ip == nil) then
            print("no (more) matching config lines found")
            break
         end
         local pattern = "(%d+%.%d+%.%d+%.%d+)%/"
         local ip = string.match(s,pattern,f_ipe+1)
         print("ip ",ip)
         table.insert(adapters,ip)
         i = f_ipe+1
      end
      return adapters
   end


   local extract_ip = {
      Windows = extract_ip_windows,
      Linux   = extract_ip_linux,   }
   local adapters = extract_ip[oss](config)
end

Re: Getting local IP address using UDP?

Posted: Fri Apr 22, 2022 10:51 pm
by togFox
My enet stuff is here.

https://github.com/togfoxy/MarsLander/b ... tstuff.lua

The game is finished and works on lan.

I'm on mobile so you'll need to search for socket code and see how that is set. Probably in love.load().

It is only one line of native love code.

Edit:

local socket = require 'socket' -- socket is native to LOVE but needs a REQUIRE
HOST_IP_ADDRESS = socket.dns.toip(socket.dns.gethostname())

GAME_SETTINGS.hostPort = "22122"