Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Unity 2022.2 is now available as the latest Tech release.
    Dismiss Notice
  3. We are making some changes to the DOTS forums.
    Dismiss Notice
  4. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Question IP for NetworkEndPoint for WiFi connection

Discussion in 'Unity Transport' started by SimonVigMillard, Feb 2, 2022.

  1. SimonVigMillard

    SimonVigMillard

    Joined:
    Jul 25, 2018
    Posts:
    13
    Hi,

    I apologize if this is not the correct forum for this question. I use Unity Transport, but I'm not sure if this is a Unity Transport issue or if it lies outside the scope of this forum.

    The challenge I'm facing is setting up the NetworkEndPoint on host and client with the correct IP and port, so a direct connection can be established over WiFi (this is for local games on iOS and Android). I have some very simple code for hosting and joining.

    Code on host:
    Code (CSharp):
    1. if (NetworkEndPoint.TryParse(hostIp, 9000, out NetworkEndPoint endpoint))
    2. {
    3.                 if (m_Driver.Bind(endpoint) != 0)
    4.                     Debug.Log("Failed to bind to port");
    5. }
    Code on client (note that the hostIp is acquired by the clients by scanning a QR code on the host device, and this works consistently):
    Code (CSharp):
    1. if (NetworkEndPoint.TryParse(hostIp, port, out NetworkEndPoint endpoint))
    2. {
    3.                 m_Connection = m_Driver.Connect(endpoint);
    4. }
    This code works most of the time, but sometimes the IP used to host the game cannot be joined, even though the devices are connected to the same WiFi or Hotspot.

    I've tried using both
    Code (CSharp):
    1. System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
    and
    Code (CSharp):
    1. System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName())
    to find the correct IP to host with. But pinpointing which IP to use seems to be very tricky. E.g. the host often has a long list of NetworkInterfaces to chose from, and finding the correct one does not seem to be a simple task.

    So basically the question is: How can I find the correct IP to host on, to make sure clients can connect? Is there a library or existing code somewhere out there which can help with this? (I've tried searching, but can't find anything)
    And also, assuming the devices are connected to the same WiFi and the correct IP is used, should it always be possible to establish a connection?

    Many thanks for your help, and please let me know if more information is needed or if this belongs in a different forum.
    /Simon
     
  2. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    155
    You can bind to "0.0.0.0" on the host, this will make the driver listen on all available local addresses.
     
    SimonVigMillard likes this.
  3. SimonVigMillard

    SimonVigMillard

    Joined:
    Jul 25, 2018
    Posts:
    13
    Thank you very much for the reply Simon - that suggestion makes a lot of sense. Just one question: Which IP should the clients connect to then? Do I just find any available address on the host and make the clients connect to that?
     
  4. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    155
    Unfortunately I'm not sure you can just pick any address. Some of them might be for internal use only (say for VMs or the like). Others might be link-local addresses which might not always work well.

    I stumbled upon this hacky method to get the local address. Seems like it could be an option.
     
    SimonVigMillard likes this.
  5. SimonVigMillard

    SimonVigMillard

    Joined:
    Jul 25, 2018
    Posts:
    13
    We tested this approach and it seems to work most of the time, but still there are scenarios where it doesn't work. For example we tried two different games with two different phones (1 iOS and 1 Android) sharing a hotspot and then hosting on the same phone. In both of these cases all other devices (connected to the hotspot) could not join (host IP was e.g. 10.207.64.175). But when one of the other phones (connected to the hotspot) hosted a game, then all phones could connect (also the phone sharing the hotspot). In this case host IP was e.g. 192.168.243.140, which seems more like the correct IP. So it seems like, for some reason, the phone sharing hotspot cannot host, but other phones connected to that hotspot can host...
     
  6. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    155
    My guess is that the hotspot phone chooses its WAN interface when connecting to an external IP address like 8.8.8.8. So the method I linked to would give you its external IP address, which makes sense I guess.

    I guess one solution would be for your clients to attempt a connection to the address provided by the method above, and if it doesn't work, to fall back on connecting to their default gateway (the assumption being that if it fails, then the host is your hotspot and thus the default gateway of your clients). You can configure a shorter connection timeout to make this process a bit less apparent to the users.

    Now the real solution here would be to move away from having the host advertise its IP address using a QR code. Normally multiplayer games on local networks would use some sort of discovery protocol (e.g. client figures out the host's address by broadcasting its presence and having the host respond). Here's one existing implementation. I'm sure there are others out there too, or you could write your own. You could also use services like mDNS (but if it's not already set up on your network, it might not be worth the trouble).
     
    iclosed likes this.
  7. SimonVigMillard

    SimonVigMillard

    Joined:
    Jul 25, 2018
    Posts:
    13
    Hm, that's interesting. In the implementation you linked to it says "Note: Network discovery only works on LAN and might not work in some networks." Is it simply the case that connecting devices like this, via LAN, is realistically not always possible? We're interested in a "fool proof" solution, that would work consistently, but perhaps that is just not possible, and we would have to be happy with it working "most of the time"? If we want to make sure that it works consistently, would it perhaps be a better option to host the game on a remote dedicated server (over the internet), rather than having one of the local devices acting as local server and host? Would that solution have a higher chance of working consistently (because we control the server)?
    Thinking about it, it seems like local connection should be easier to achieve, but our experience trying to get this solution to work consistently, has made as think that perhaps an online solution would be easier...
     
  8. simon-lemay-unity

    simon-lemay-unity

    Unity Technologies

    Joined:
    Jul 19, 2021
    Posts:
    155
    Will all the players in a game session always be on the same network? If so then I think it's fair to assume that a network discovery protocol should work quite reliably. The only instances I can think of where it wouldn't work is if the network has some unusual configuration (say if it limits the usage of multicast/broadcast addresses).

    You can always combine the approaches too if you want to ensure it works. Say you start by trying to find a host on the local network using a discovery protocol, and if that fails, you switch to connecting on the internet. Although in that last scenario you may be better served by a relay server rather than a dedicated server. It's cheaper and you will be able to keep the player-hosted architecture of the game. Unity has a relay service in beta currently (there are other providers too).
     
    SimonVigMillard likes this.