Search Unity

Question Can't get Android's (tablet) Local IP address

Discussion in 'Netcode for GameObjects' started by GuirieSanchez, Nov 28, 2022.

  1. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    I've been using this code to get the local IP of the device:

    Code (CSharp):
    1. public static string[] GetLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    2.         {
    3.             var ipAddrList = new List<string>();
    4.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    5.             {
    6.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    7.                 {
    8.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    9.                     {
    10.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    11.                             ipAddrList.Add(ip.Address.ToString());
    12.                     }
    13.                 }
    14.             }
    15.             return ipAddrList.ToArray();
    16.         }
    And it works fine and dandy for PC, Mac, and iOS (both for hosting and for joining as a client in each device).

    Now, when I built it for Android, I get no info for the local IP:

    upload_2022-11-28_14-10-10.jpeg

    Also, I'm not able to join as a client to any available host's local IP, which makes me think it might have something to do with networking permissions, but maybe not, I have no idea.

    I tried this method showcased in this UnityAnswers:

    which is adding this line of code (android:usesCleartextTraffic="true") to the app manifest
    upload_2022-11-28_14-15-13.png
    to
    upload_2022-11-28_14-16-28.png

    But to no avail, it doesn't help. Also, after building it, the manifest apparently gets reset and that line disappears.

    I also tried to find any permissions for the app regarding the network, but I don't seem to find any (although I think it has to have permissions on.

    Any help would be highly appreciate it.
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    5,870
    Maybe the device is only using an IPv6 address? Try getting that instead.
    Also add some logging in the foreach loop or step through the loop with the debugger to see what kind of interfaces are available and what their IPs are.
     
    GuirieSanchez likes this.
  3. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Hi, thanks for replying. I'm coming back home tonight so I'll give that a shot. Is there a way to make sure to detect whatever local IP they have? I feel like I could have IPv6 and IPv4, and then I may have some problems in the future if there's a new one that I don't cover in code. Also, I tried on a second iPhone, and that iPhone also didn't ask for permissions to join the local network, which may be due to what you said (IPv6):



    On the first iPhone and the iPad this message was triggered and therefore I was able to join the local network. From that on, the app appeared on the local network section of the settings so one would be able to deactivate it or activate as they please.

    Anyway, I'll try to put both one after another. If you can, let me know if this code is correct:


    Code (CSharp):
    1. public static string[] GetLocalIPv6(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    2.         {
    3.             var ipAddrList = new List<string>();
    4.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    5.             {
    6.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    7.                 {
    8.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    9.                     {
    10.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    11.                             ipAddrList.Add(ip.Address.ToString());
    12.                     }
    13.                 }
    14.             }
    15.             return ipAddrList.ToArray();
    16.         }
     
  4. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    upload_2022-11-29_23-40-54.png
    Sorry, this is the image I was trying to upload.

    Also, the whole piece of code is the following:
    Code (CSharp):
    1. public static string GetPublicIPv4()
    2.         {
    3.             var ipString = new WebClient().DownloadString("http://icanhazip.com");
    4.             return ipString.Replace("\\r\\n", "").Replace("\\n", "").Trim();
    5.         }
    6.  
    7.         public static string[] GetLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet)
    8.         {
    9.             var ipAddrList = new List<string>();
    10.             foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
    11.             {
    12.                 if (netInterface.NetworkInterfaceType == interfaceType && netInterface.OperationalStatus == OperationalStatus.Up)
    13.                 {
    14.                     foreach (var ip in netInterface.GetIPProperties().UnicastAddresses)
    15.                     {
    16.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    17.                             ipAddrList.Add(ip.Address.ToString());
    18.                     }
    19.                 }
    20.             }
    21.             return ipAddrList.ToArray();
    22.         }
    23.  
    24.         public static string GetFirstLocalIPv4(NetworkInterfaceType interfaceType = NetworkInterfaceType.Ethernet) =>
    25.             GetLocalIPv4(interfaceType)?.FirstOrDefault();
    26.  
    27.         public static IPAddress[] ResolveHostname(string hostName, bool ip6Wanted = false)
    28.         {
    29.             // hostname may already be an IP address
    30.             if (IPAddress.TryParse(hostName, out var outIpAddress))
    31.                 return new[] { outIpAddress };
    32.  
    33.             try
    34.             {
    35.                 var addresslist = Dns.GetHostAddresses(hostName);
    36.                 if (addresslist == null || addresslist.Length == 0)
    37.                     return new IPAddress[0];
    38.  
    39.                 if (ip6Wanted)
    40.                     return addresslist.Where(o => o.AddressFamily == AddressFamily.InterNetworkV6).ToArray();
    41.  
    42.                 return addresslist.Where(o => o.AddressFamily == AddressFamily.InterNetwork).ToArray();
    43.             }
    44.             catch { }
    45.  
    46.             return null;
    47.         }
    48.  
    49.         public static string TryResolveHostname(string hostName, bool ip6Wanted = false) =>
    50.             ResolveHostname(hostName, ip6Wanted)?.FirstOrDefault()?.ToString();
    I think it covers the IPv6, right? So it might be something else
     
  5. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Ok, so I even tried it with this method from this thread:

    Code (CSharp):
    1. public class IPManager
    2. {
    3.     public static string GetIP(ADDRESSFAM Addfam)
    4.     {
    5.         //Return null if ADDRESSFAM is Ipv6 but Os does not support it
    6.         if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
    7.         {
    8.             return null;
    9.         }
    10.         string output = "0.0.0.0";
    11.         foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    12.         {
    13. #if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
    14.             NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
    15.             NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
    16.             if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
    17. #endif
    18.             {
    19.                 foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
    20.                 {
    21.                     //IPv4
    22.                     if (Addfam == ADDRESSFAM.IPv4)
    23.                     {
    24.                         if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
    25.                         {
    26.                             if (ip.Address.ToString() != "127.0.0.1")
    27.                                 output = ip.Address.ToString();
    28.                         }
    29.                     }
    30.                     //IPv6
    31.                     else if (Addfam == ADDRESSFAM.IPv6)
    32.                     {
    33.                         if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
    34.                         {
    35.                             if (ip.Address.ToString() != "127.0.0.1")
    36.                                 output = ip.Address.ToString();
    37.                         }
    38.                     }
    39.                 }
    40.             }
    41.         }
    42.         return output;
    43.     }
    44. }
    45. public enum ADDRESSFAM
    46. {
    47.     IPv4, IPv6
    48. }
    But to no avail. With the previous code that I showed and the new code shown right here (using both IPv4 and IPv6), I got either an empty Local IP (and public) or I get these seemingly random numbers:
    upload_2022-11-30_1-7-22.png
     
  6. GuirieSanchez

    GuirieSanchez

    Joined:
    Oct 12, 2021
    Posts:
    452
    Little update:

    I was using the iPhone's 4G data as wifi connection for the android device so far. When I connected to a WiFi router, however, it did work. I don't know why mobile data is not ok for using local IPs.
    Now I tested again on the same iPhone, and, if I use data, I get this local IP format (of this kind xxx.xx.xx.xx, which might work), but unfortunately most of the time I get no Local IP at all.

    What is weirder though is that yesterday I was on I trip and I used the same iPhone with data and an iPad connected to that iPhone's 4G, and it worked without an issue... This is a mystery to me, I have no clue about what's going on, so any clarification on the matter is highly appreciated.

    PS: Ok, I found out something basic about how the local network works (so I apologize for making a mess out of this). All devices must be connected to the same connection (either to the same WiFi router, 4G, 5G, or whatever), or else it won't work (again, sorry for bringing something this basic). Now, if I wanted different devices to connect to a host with their respective connection (maybe each client is connecting from their home), then I thought they could join with the Host's public IP:


    Code (CSharp):
    1. public static string GetPublicIPv4()
    2.         {
    3.             var ipString = new WebClient().DownloadString("http://icanhazip.com");
    4.             return ipString.Replace("\\r\\n", "").Replace("\\n", "").Trim();
    5.         }
    But they don't seem to be able to connect by using the Host's public IP.
    So, the current situation is: why sometimes the Host's local IP is null? and how does the Public IP work? because it doesn't seem to be useful for connecting clients to the host.
     
    Last edited: Nov 30, 2022