Page 3 of 4

Re: UDP networking for multiplayer game

Posted: Wed Apr 03, 2019 7:20 pm
by mxmlnbndsmnn
Ok :o
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 ^^).

Re: UDP networking for multiplayer game

Posted: Wed Apr 03, 2019 8:50 pm
by keharriso
I got it working by taking out the "if connected" code and using "0.0.0.0" instead of "*". Check out the attached files.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 1:01 pm
by mxmlnbndsmnn
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

Code: Select all

local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
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.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 1:41 pm
by keharriso
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.
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 2) What does this

Code: Select all

local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
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.
It looks like sendto returns the number of bytes sent instead of 1. This is likely an error in the documentation.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 2:22 pm
by zorg
keharriso wrote: Thu Apr 04, 2019 1:41 pm
mxmlnbndsmnn wrote: Thu Apr 04, 2019 1:01 pm 2) What does this

Code: Select all

local a, b = udp:sendto("promo", "255.255.255.255", clientPort)
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.
It looks like sendto returns the number of bytes sent instead of 1. This is likely an error in the documentation.
And the string "255.255.255.255" being sent is 5 bytes long? Not seeing any compression done there...
Edit: Wow, i'm more blind than i thought, sorry bout that. :oops:

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 2:23 pm
by keharriso
No, the string being sent is "promo". "255.255.255.255" is the broadcast address.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 2:28 pm
by mxmlnbndsmnn
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)

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

Posted: Thu Apr 04, 2019 3:07 pm
by pgimeno
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.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 3:21 pm
by keharriso
pgimeno wrote: Thu Apr 04, 2019 3:07 pm 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.
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.

Re: UDP networking for multiplayer game

Posted: Thu Apr 04, 2019 3:37 pm
by pgimeno
Um, yeah, I haven't used UDP that much :oops: (but there's another way, to forge sender addresses)