GNet Connection Problems

BlitzMax Forums/BlitzMax Programming/GNet Connection Problems

TheTophatDemon(Posted 2014) [#1]
So, I have a basic 2d multiplayer deathmatch thingy. When I test it using a local IP (127.0.0.1) it works exactly the way I want it. However, if I'm using a public IP and a forwarded port it doesn't. Basically, GNetConnect returns false. That's all it gives me, though, and I looked through the source code only to find it's because ENet's connect function returns false. Any ideas as to why? The port I use is 25565. And this is the game. Also, please don't bother correcting my giant mass of spaghetti code unless it has to do with the problem I am having.


TheTophatDemon(Posted 2014) [#2]
So, does GNet only work for LAN games? From all the documentation and examples, it doesn't really say anything about the matter.


markcw(Posted 2014) [#3]
Have you tried mark sibly's gnetdemo? It's in samples/mak along with gnetchat

There is an extended version by Mahan here
http://www.blitzmax.com/Community/posts.php?topic=81799


markcw(Posted 2014) [#4]
I've been trying myself using mak/gnetchat on 2 pcs today and no luck either yet. Tried turning off firewalls but still nothing. Tried other demos still nothing.

Rimmsy had problems too here http://www.blitzmax.com/Community/posts.php?topic=77872


markcw(Posted 2014) [#5]
I think this is the problem. I'm on a wireless router and need to forward the port.

http://www.blitzmax.com/Community/posts.php?topic=70738
http://www.blitzmax.com/Community/posts.php?topic=49479

You can also try Hamachi or UPnP, instead of port forwarding.

http://www.blitzmax.com/Community/posts.php?topic=95258
http://www.blitzmax.com/Community/posts.php?topic=80012


markcw(Posted 2014) [#6]
Just tested gnetchat on 2 pcs with ethernet (instead of wireless) and firewalls off (but no port forwarded) and it still failed to connect.

I did a test with port forwarding yesterday (using 2 wireless pcs) but it didn't work either. Probably didn't set it up right though.


Derron(Posted 2014) [#7]
I can assure that it is a problem on YOUR code/side not on the gnet one itself.

I have no demo for gnet (I use my own layer to enet - with copied parts of gnet) but as it works for me, it should work for you.

If you are not sure whether there is communication going it / coming in: use a paket sniffer like wireshark and observe communication.

I had problems with "broadcasting" (sending to x.x.x.255 or whatever the broadcast address is in your LAN setup - default is .255) to announce lan games to all computers in the same subnet. This wasn't working with enet/gnet. Had to misuse another port and code (headers and 1 function) from BNetEx to get this working.


bye
Ron


xlsior(Posted 2014) [#8]
I had problems with "broadcasting" (sending to x.x.x.255 or whatever the broadcast address is in your LAN setup - default is .255)


Note that the broadcast address is dependent on the value of the netmask as well.

It's it's x.x.x.255 if your netmask is 255.255.255.0, but could be x.x.y.255 or x.y.y.255 if you use larger subnets, which can often be the case if you're using the 10.x.x.x or 172.16.x.x through 172.31.x.x.address ranges on your local LAN.


Derron(Posted 2014) [#9]
If you have a larger network you certainly should have a contact person knowing how to handle broadcasting in that case.

My whole hardware is using 192.168.x.0-255 as their defaults (my personal one is 192.168.0.x but routers tend to have dhcp defaults of x.x.1.x or x.x.2.x - had this on 4 routers, 2 aps and 1 nas).

But thanks for the hint, might be of use for some of the thread readers.

bye
Ron


markcw(Posted 2014) [#10]
Well I've been able to connect on gnetchat over my lan (with 2 wireless pcs) but not to my public ip, even though I switched off the router's firewall (I used "netstat -rn" to find router/gateway ip from terminal and then typed that into my browser url).

Each pc has it's own local ip 192.168.x.0-255 in my case. Testing on my lan each pc firewall worked as expected, blocking access until I either disabled it or allowed the port/application access (gnetchat uses udp).

So now I wonder, is it not possible for 2 pcs using the same public ip address to connect to eachother?

Edit: I think I found the answer.
http://www.tomshardware.co.uk/forum/28816-42-connect-computers-server


Derron(Posted 2014) [#11]
Was there a time where you wondered how this would work without NAT ?

Computer A and Computer B are in the same "LAN", they have IP
A: 192.168.0.1
B: 192.168.0.2

Your "public ip" is eg. 100.101.102.103.

Now A hosts a chat. B wants to connect over 100.101.102.103. A receives a packet from 100.101.102.103 (this is the ip from the sender when a packet goes "outside"). A now has to decide whom this package belongs too. A has the same IP so he must think: its mine.

To avoid this, use ports. It is just to distinguish clients sharing the same ip.
In the case of udp you cannot select what port is used (by default) - it just uses a "free one" (not occupied by another client).
The target port is the one, the "server" is listening to.

So on your router you have to setup the "target port" to get routed to the pc-ip hosting the server. There is hole punching (sender of a package opens receiving on the same port) but this is circumvented by nat routing.

The server of the chat now reacts on incoming packages: they contain now the public IP and a port used to send - if the server now responds to this, the hole punching should work and the client B should receive the package (public ip + target port).
As you can manipulate what "port range" to use for sending, you can even adjust your NAT for client B.


bye
Ron


markcw(Posted 2014) [#12]
Yesterday actually. lol

These things are not self-explanatory. Is there a good website or tutorial/s that I can read about networking perhaps?

I gather that a NAT (network address translation) is a router that uses 1 ip for several lan pcs.

So 2 pcs on the same lan *can* use the same public ip as long as they are using 2 different ports. And this is possible with both tcp and udp?

I'm a little confused, looking at the gnetchat sample it doesn't say whether udp or tcp is being used. How do you find out from the source what is being used? When I set up my firewall to allow port x in, it only worked with udp so I assume that's what gnetchat uses.

So the "target port" is the one the server pc uses? And there are two ports for the server, one for send and one for receive?


Derron(Posted 2014) [#13]
NAT ... is a "feature" your router provides... it routes incoming packets to their corresponding receipients on the lan.

It is possible for TCP and UDP. a "server" can receive multiple packets (coming from multiple ips, multiple ports ...) on ONE port. Each computer has a unspecific amount of "ports" you can use. But you can use a specific port only once at a time.

That is why you can often setup the "listen to" port, but not the "sender". As you often want to limit the sending port too - you can do something like a "port range" which your networking class then can use (it starts by the first in the range - if not available - eg another client on the same computer occupies it - it uses the next and so on).

I think Gnet relies on ENet which is using UDP.

For UDP you mostly do not directly say which port to use for sending, you just say on which you are receiving things. So each client has its own "target port" at which he wants to receive its packets.

If you have server and client in one program (eg a game - one is the host but also one of the players) this wont bring you in trouble, this is possible too.

The only thing not working properly with gnet/enet is broadcasting.


bye
Ron


markcw(Posted 2014) [#14]
Okay, thanks.

So the NAT just reroutes everything automatically. I assume any router with multiple local pcs has NAT then?

Is there some sample code for this? Looking at the gnetchat sample, I don't see how I can get 2 pcs (with the same public ip) to connect while using different ports.

Would it not be easier to connect in pairs, favouring local before public? I am thinking of a 2-4 player game, so for example if A and B are on the same lan and C and D are on separate public ips. Then if I establish a chain of connections B-A, A-C and C-D so there's 3 server/client connections, then I can transfer data across the chain. Or is this more complicated?


Derron(Posted 2014) [#15]
For a client it should not matter where he connects to. A server has to be even more straight forward ...

To distinguish between Player B and C (both from the same remote public ip adress) you can't use their sender-ports as they might be the same, but you can use playerhashs or other individual data to identify them.
Another option is to make the senderport-range "configurable" so you allow Player B's client to use port 1010-1020,and Player C's client to use Port 1021-1030. So if they both connect you can distinguish them. If you cannot distinguish them, you just disconnect the "one entered first" - it is then their problem to fiddle around what to do (configure their client).

Every router has NAT. There were times with pcs being the router (the times of analog modems) so even your PC can do NAT but by default it is exposed to the internet by public ip then (if you want to learn more about it: google "ICS windows").


Example: Like said I am not using GNet and therefor cannot give an example yet. I directly communicate using enet + some classes of gnet + my own implementation to handle login-requests, information channels (broadcasted game announcements on LAN) etc.

bye
Ron


markcw(Posted 2014) [#16]
Well you've lost me now.

Saying as I understand my chain idea I will try that and see how it goes. Only problem is I don't know how to list any active local ips yet. Hopefully there is some code around somewhere for that.

Edit: well this looks promising.
http://www.blitzmax.com/Community/posts.php?topic=98149

Or this.
http://www.blitzmax.com/Community/posts.php?topic=75387


Derron(Posted 2014) [#17]
To search a "server" on the lan isn't the right way to do so - because you then need to scan the whole LAN.

Better broadcast from the server .... so all active IPs get the package automatically.

So your clients just have to wait for packets... list the sender as active server (with a lifetime in which the server has to resend the packet again).


Don't be shocked by the following code - you will NOT need all of this, but maybe you get an idea how to handle that problem:

Basic network implementation:
https://github.com/GWRon/TVTower/blob/master/source/basefunctions_network.bmx

game specific extension:
https://github.com/GWRon/TVTower/blob/master/source/gamefunctions_network.bmx



bye
Ron


markcw(Posted 2014) [#18]
Well thanks, that looks scary (but tidy). I'm surprised how many people have written their own network modules when gnet already works pretty good.

I think I know one quick and dirty way to "broadcast" the pcs local ip. You can use the gnet "lobby" and in the server name slot send the local ip (and in encrypted form would probably be a good idea). So if everyone sends their global and local ips to the lobby it would be obvious when 2 or more pcs are on the same lan.

http://www.blitzmax.com/codearcs/codearcs.php?code=2818
And http://www.blitzmax.com/codearcs/codearcs.php?code=1413


Derron(Posted 2014) [#19]
I had to write it because:
a) I used my custom implementation before recognizing some benefits of gnet (that "object" handling with 32 slots)
b) gnet does not provide everything I want: broadcasting, localhost-players

So I had to do some things on my own.


You need: their ip + their port for the first connection. Hole punching works the way, that the router knows who sent a packet - so answering to it, should automatically get routed to the correct sender in your lan. Afterwards (eg. you answered with "yeah, you can join, there is space left - use this clientID pls") the one in the lan can use his clientID to identify together with IP+port.


bye
Ron


markcw(Posted 2014) [#20]
Well I wrote a GetLocalIP function for use in fake broadcasting via the gnet lobby
http://www.blitzmax.com/codearcs/codearcs.php?code=3122

I realised that the server_name slot is for this purpose, hence the name - it says in the gnet_v1 doc it's for level names. So I googled and it does say sharing the local ip address is a security risk but you can send the local name and it can be converted to the local ip when received by a pc on the same lan.

I also realised it would be possible to set up a global/local server network instead of a chain network, where no 2 pcs would connect to the same global ip. It might be more complicated but would be better for anything more than 4 players. You could add an int after the gnet server name like this-pc/1 that would specify who was the global server (only 1) and who was a local server for their own lan. The first pc would become global server and the first from every global ip would be local server. I just have to code it now. lol

Does your code find ports too? I'm just going with a set port that can be customized if needed.

Thanks for all the help.


Derron(Posted 2014) [#21]
I am not "finding" ports as the "lan port" is a fixed one - the online port can differ.
Of course this then wont allow multiple servers on one computer. Exception is: you have a real server programme which is able to handle multiple "sessions" incoming on one port. Else you would have to add broadcasts for each used port - and clients would have to listen to each of the ports - how should they know?
So: each of your "game binaries" can only host one game. Only one "host" per computer is allowed/possible.
Clients are allowed more than one: they connect to the given port with a one free for them. Next client on same computer just uses another sender port to target the same one like the prior one did.
This works because the clients initiate the connection: they start talking with the host/master - so the master does not have to know what ports MIGHT be used... he just gets a package at his one and only open port... with a sender ip and port.

It is like your living address with house number: people can ring at your home without you needing to know where they live - but once you opened the door, you can ask them where they come from.



I oriented my code/approach to the Lobby mechanism of Warcraft III.

Instead of using "server_name" you can also use the local ip directly - as this is also "unique" in a lan. The name used in the LAN has to get read which needs other codelines.

Instead of modifiying the "identification" of a client to set it as master/server, you just add another variable in the packet.

When connecting a client to a master, your client already knows: this is the master. The master also already knows: I am the master, all connections are coming from clients.


so in short:
you create a "server": set a variable "server" to true
you try to connect to a server: reset that variable "server" to false.


bye
Ron