[Networking] Internet LAN punchthrough

Most of my other networking issues are now solved. But I have a new one. I’m using GameSparks to create matches and handle NAT Punchthrough. This works; yay :slight_smile:

When two devices are on different internet networks; such as phone using cell data, and my home computer on my home internet. both devices work. I am playing over the internet with my functioning NAT punch through. However, once I bring my phone on WiFi and I’m using the same external IP address. things fail again.

One solution is to just do LAN play. However, this is a problem. If say 2 players are in one house, but 2 other friends are elsewhere. Then the host and the two outside friends will play together, but the friend next to the host can’t play.

1 Like

can you share some information how you’ve done it? Need to archive this in a feew weeks too and don’t want to reinvent the wheel :slight_smile:
Beside of this we need more information how you created the Punch - so for example if you use a specific source port on every client it will allways fail with a second device as this source port is already in use and most of the internet router/modems don’t track the connection correctly. I expect you’re using UDP? or TCP or UPNP?

Clients connect to the master server and associate their external ip address to their online data.

  1. A Client clicks the join game button
  2. The system hunts down available potential game from a persistent cache
  3. If it finds no match the master returns info to the client to become a host. Server also saves this new game info into a persistent data cache
  4. The client then does a “open mapname?listen” to become the host server
  5. another client will click join game
  6. master hunts down an available game from the cache
  7. Finds an available game
  8. Sends the host the joining clients external ip to the host(only the ip, no port)
  9. host does a sloppy Call URL to the “externalip:7777”( I couldn’t use open because that closes the current listen state)
  10. master sends client the host external ip
  11. joining client player will then do a “open hostip”

When both players on different LANs this works. However, upon the same LAN this fails.

I removed the 7777 reference from url punch through call( step 9 ), but that didn’t work either :frowning:

No answer exactly how to make this work on the NAT punch through. However, have tested a solution.

If the joining client external Ip is the same as the host Ip. Then the idea is to send the joining client the host internal IP. I’ve tested this theory by manually typing in the IP address for localhost. But this is, of course ineffective. So now I have a new problem that I can use an answer to.

NEW QUESTION
How do I get the local IP address?

My C++ is as I’ve found out extremely rusty and that I feel like I’m back being a newb. I’m also having difficulties getting around UE4 C++ side of development and library patterns.

If anyone can lend assistance to helping me get the local IP I would be very appreciative.

This is the only source I can find on the subject. but since my c++ is rusty, I don’t have enough context to flesh out the rest or even figure out how I would access the return from BluePrints.

My issues are solved. I’ve written a C++ BluePrint function library. In it currently, there is a way to get the local IP address. Which works great for ipv4. I haven’t checked ipv6 though. I will also be adding a socket based NAT punch through. Instead of the clumsy call URL… which does function. The NAT punch through is just a connect/ping or something.

Hi jayderyu, I am attempting to implement NAT punchthrough as well right now and since it seems like you are able to get it working, I was wondering if you would be willing to share a bit more details about what you did.

I noticed that in step 9, you indicated that the host "did a sloppy Call URL " to client’s external ip at port 7777, did you use the LaunchURL node in blueprint? How exactly did you make this sloppy URL call?.

Secondly, did step 9 and step 11 have to happen simoutaneously for you? Did you have to retry step 9 and 11 multiple times?

Thanks for your help

  1. I did use the LaunchURL node. When in the editor running as the server, this would open a browser. However, on the Android device, it was fine and worked without an issue. Though I still feel that this is not ideal and a socket call would be better.

  2. It’s not at the same time. You want to make sure that the server tried to contact the clients before the clients contact the server. The server is going to fail contact and that’s ok. What’s important is that the server is telling the router to unlock the door for that specific computer. It would be best that upon 9 finishing the NAT punch it would then be best for the server to call the master that it is complete. Then the master would greenlight the clients that the door is unlocked and can connect to the server. I was lazy and put in a 5-second delay on the client side.

How did you do #8? How does one connect/send info to an address without traveling to the level?

There needs to be a backend server say for matchmaking. In my sample above I used GameSparks. When a client connects to GameSparks I would also send the internal and external IP address of the client. This way the backend can assist in the doing host client setup. Otherwise players would need to share the IP manually.

Aloha @jayderyu,

Can you share your socket-based NAT punch through plugin? It doesn’t seem to work for me using your method, at least for mobile. I’m also using GameSparks for matchmaking. Any help is appreciated!

Moved to reply

Well, I haven’t used it or worked on it for a while. Since then I’ve inadvertently got rid of the project without making a backup when I needed a massive HDD clean. It really didn’t do anything fancy and only consisted of 1 function and was having the server ping the client.

My method was targeted for mobile as that’s how I was testing. However, I did find that connecting the server internally on the same network and different networks required different approaches.

If you share what you have I can take a look and assist.

@jayderyu - Thanks for responding.

I’m at work and don’t have access to my source at the moment; however, I can give you a brief overview of what I’m trying to achieve.

Right now my game is functioning with local multiplayer; however, local multiplayer is only for testing to get the game functioning. Once we tried to test between two phones, on their own cellular networks (internet), we are unable to get the two phones to connect. One phone is acting as a listen server (host) and the other is a client that presses a hard-coded button containing a console command node with “open [hostIP]:7777”. When testing between a PC and phone, I can get a phone to connect through to my PC’s external, but my home network has open NAT so that’s why it works. I can’t ask everyone to port forward on their home networks, plus I want players to be able to play anywhere, as long as they have cellular network signal. Thus, the reason for NAT punchthrough :slight_smile:

Before matches can start, I run through a simple matchmaking process within GameSparks to connect the two separate player accounts together in the same match. Then click the host button on the host, then click join button (again with hard-coded external IP of host), and it doesn’t work.

I also added a button on the host screen that calls the LaunchURL node to the client’s external [IP:7777]. It loads a browser, then when I try to connect from the client phone to the host’s IP, it still doesn’t let the client into the host’s session.

Only thing I haven’t set up is the passing of external IP’s directly into GameSparks and storing it somewhere to pass between host/client, but because I’m hard-coding it all at the moment, I didn’t think that was needed.

Thanks again!

hmm. I found that using phone IP to be awkward and unreliable. I think in the end I had to use a call to a rest service to get the external IP. What was reported on the phone didn’t match up to what I found from say my IP4(http://whatismyip4.com/). I can’t say for sure if this is the same problem you having. Maybe you already are, but double confirm that IP address is external by using the website from the phone.