Ok
I dont really see a walkaround here so I will probably just stick to the less friendly method of having the users input the address manually. At least for now (I dont like giving up ).
UDP networking for multiplayer game
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
-
- Prole
- Posts: 37
- Joined: Mon Feb 11, 2019 4:17 pm
Re: UDP networking for multiplayer game
I got it working by taking out the "if connected" code and using "0.0.0.0" instead of "*". Check out the attached files.
- Attachments
-
- udp-broadcast-example.zip
- (2.69 KiB) Downloaded 194 times
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
-
- Prole
- Posts: 37
- Joined: Mon Feb 11, 2019 4:17 pm
Re: UDP networking for multiplayer game
Interesting that this work but the actual broadcast method does not (at least on the systems you mentioned).
Tried it in a LAN and worked
Now that the sockname is set to "0.0.0.0", using getsockname() always returns this useless "address". Obviously when using receivefrom and sendto after the first "handshake" has been made, the server knows the IP address from the connected client(s) but not himself (well somehow he must know it ... but getsockname won't help me there). Same thing on the client side. I thought about both server and client sending the address information about their counterpart TO their counterpart and after that killing the connection and then set it up again ... but that sounds stupid tbh
Two more things...
1) You said do not use setpeername at the client. Why? It feels wrong/bad to use sendto instead of "binding" the socket and then simply use send. Should be a slight performance gain, too.
2) What does this output on your machine? I am getting 5 and nil.
Why am I asking, you ask? Because the reference says "If successful, the method returns 1. In case of error, the method returns nil followed by an error message." (http://w3.impa.br/~diego/software/luaso ... tml#sendto) Hm ... ? I haven't found any more detailed description of the return values.
Tried it in a LAN and worked
Now that the sockname is set to "0.0.0.0", using getsockname() always returns this useless "address". Obviously when using receivefrom and sendto after the first "handshake" has been made, the server knows the IP address from the connected client(s) but not himself (well somehow he must know it ... but getsockname won't help me there). Same thing on the client side. I thought about both server and client sending the address information about their counterpart TO their counterpart and after that killing the connection and then set it up again ... but that sounds stupid tbh
Two more things...
1) You said do not use setpeername at the client. Why? It feels wrong/bad to use sendto instead of "binding" the socket and then simply use send. Should be a slight performance gain, too.
2) What does this
Code: Select all
local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
Why am I asking, you ask? Because the reference says "If successful, the method returns 1. In case of error, the method returns nil followed by an error message." (http://w3.impa.br/~diego/software/luaso ... tml#sendto) Hm ... ? I haven't found any more detailed description of the return values.
Re: UDP networking for multiplayer game
This one I honestly don't know the answer to. For some reason, I was getting an error with setpeername. You can try adding it back in now that everything is working.mxmlnbndsmnn wrote: ↑Thu Apr 04, 2019 1:01 pm 1) You said do not use setpeername at the client. Why? It feels wrong/bad to use sendto instead of "binding" the socket and then simply use send. Should be a slight performance gain, too.
It looks like sendto returns the number of bytes sent instead of 1. This is likely an error in the documentation.mxmlnbndsmnn wrote: ↑Thu Apr 04, 2019 1:01 pm 2) What does thisoutput on your machine? I am getting 5 and nil.Code: Select all
local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
Why am I asking, you ask? Because the reference says "If successful, the method returns 1. In case of error, the method returns nil followed by an error message." (http://w3.impa.br/~diego/software/luaso ... tml#sendto) Hm ... ? I haven't found any more detailed description of the return values.
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
- zorg
- Party member
- Posts: 3465
- Joined: Thu Dec 13, 2012 2:55 pm
- Location: Absurdistan, Hungary
- Contact:
Re: UDP networking for multiplayer game
And the string "255.255.255.255" being sent is 5 bytes long? Not seeing any compression done there...keharriso wrote: ↑Thu Apr 04, 2019 1:41 pmIt looks like sendto returns the number of bytes sent instead of 1. This is likely an error in the documentation.mxmlnbndsmnn wrote: ↑Thu Apr 04, 2019 1:01 pm 2) What does thisoutput on your machine? I am getting 5 and nil.Code: Select all
local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
Why am I asking, you ask? Because the reference says "If successful, the method returns 1. In case of error, the method returns nil followed by an error message." (http://w3.impa.br/~diego/software/luaso ... tml#sendto) Hm ... ? I haven't found any more detailed description of the return values.
Edit: Wow, i'm more blind than i thought, sorry bout that.
Last edited by zorg on Thu Apr 04, 2019 6:51 pm, edited 1 time in total.
Me and my stuff True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Re: UDP networking for multiplayer game
No, the string being sent is "promo". "255.255.255.255" is the broadcast address.
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
-
- Prole
- Posts: 37
- Joined: Mon Feb 11, 2019 4:17 pm
Re: UDP networking for multiplayer game
Yep, you're right about the byte length (at least it seems so). Sending "promote" instead, returns 7 ... => approved
I figure out the setpeername error: I use receivefrom as long as the client does not know the server. Once the client gets accepted from the server, I can call setpeername and after that I have to use receive - not receivefrom. In general, that's what I'm doing but in real I had to cancel the listening once I call setpeername in one receive cycle:
(unconnected state)
I figure out the setpeername error: I use receivefrom as long as the client does not know the server. Once the client gets accepted from the server, I can call setpeername and after that I have to use receive - not receivefrom. In general, that's what I'm doing but in real I had to cancel the listening once I call setpeername in one receive cycle:
(unconnected state)
Code: Select all
repeat
local datagram, msg_or_nil, port_or_nil = udp:receivefrom()
--print(datagram, msg_or_nil, port_or_nil)
if datagram then
print("unconnected client received: " .. datagram)
if datagram == "promo" then
if not self.client.joinRequestPending then
if udp:sendto("askjoin", msg_or_nil, port_or_nil) then
self.client.joinRequestPending = true
self.client.peer = { ip = msg_or_nil, port = port_or_nil }
print(self.client.peer.ip, self.client.peer.port)
end
end
elseif datagram == "acceptjoin" then
self.client.joinRequestPending = false
self.client.connected = true
udp:setpeername(msg_or_nil, port_or_nil)
print("network: client connected to...")
print(msg_or_nil, port_or_nil)
local _ip, _port = udp:getsockname()
print("client ip: " .. tostring(_ip) .. " port: " .. tostring(_port))
break --< this dude was needed
end
elseif msg_or_nil ~= "timeout" then
print("client: Network error (2): " .. tostring(msg_or_nil))
end
until not datagram
Re: UDP networking for multiplayer game
There's a reason why it's not so easy for a server to determine its own IP address: there may be several network interfaces in the machine, each with its own IP, and even one single network interface can have several IP addresses. When the bind address is 0.0.0.0 (all interfaces), which address is used typically depends on the destination address, according to the routing table. For the global broadcast address 255.255.255.255, I guess that all IPs in all interfaces will send the broadcast, probably including localhost, for example. I haven't tested that.
With some luck, you may be able to find a way to retrieve the complete list of IP addresses that a server supports, and let the user hosting the server choose one. If there's only one after discarding 127.x.y.z, you can actually pre-configure it. I haven't found anything in the LuaSocket documentation that deals with interfaces; however it seems that you can use local _, info = socket.dns.toip(socket.dns.gethostname()) to get IP information in info.ip[1], info.ip[2] etc.. This isn't so reliable as querying the IPs of all interfaces, but it might be a start, at least something to fill the server IP entry field with initially.
And that's what I suggest for the server: to offer the user an entry field where to input the server IP, perhaps pre-filled as described above. The idea of having the clients send the server its own IP address sounds pretty insecure to me. The opposite doesn't sound too bad, though a rogue server could use that for DDoSing a machine.
I haven't even touched the possibility of having a machine connected to two local networks, with some clients in one and others in the other. In such a case, the server needs one IP for talking to one set of clients and another for talking to the other set.
With some luck, you may be able to find a way to retrieve the complete list of IP addresses that a server supports, and let the user hosting the server choose one. If there's only one after discarding 127.x.y.z, you can actually pre-configure it. I haven't found anything in the LuaSocket documentation that deals with interfaces; however it seems that you can use local _, info = socket.dns.toip(socket.dns.gethostname()) to get IP information in info.ip[1], info.ip[2] etc.. This isn't so reliable as querying the IPs of all interfaces, but it might be a start, at least something to fill the server IP entry field with initially.
And that's what I suggest for the server: to offer the user an entry field where to input the server IP, perhaps pre-filled as described above. The idea of having the clients send the server its own IP address sounds pretty insecure to me. The opposite doesn't sound too bad, though a rogue server could use that for DDoSing a machine.
I haven't even touched the possibility of having a machine connected to two local networks, with some clients in one and others in the other. In such a case, the server needs one IP for talking to one set of clients and another for talking to the other set.
Re: UDP networking for multiplayer game
Correct me if I'm wrong, but wouldn't the client and server both know each other's IP addresses simply because they exchange UDP messages? udp:receivefrom is all it takes to find out the other end's IP address. The only way I know to avoid this would be using a VPN and/or proxy.
LÖVE-Nuklear - a lightweight immediate mode GUI for LÖVE games
Re: UDP networking for multiplayer game
Um, yeah, I haven't used UDP that much (but there's another way, to forge sender addresses)
Who is online
Users browsing this forum: No registered users and 7 guests