Reputation: 71
How to get IP address on C# in program which developing for android device in Unity 2018.2+?
Seems like Network.player.ipAddress
is deprecated right now, so I'm looking for a new way.
Upvotes: 2
Views: 44876
Reputation: 1
https://stackoverflow.com/a/67450052/18192881
In regards to the geofilter data post, according to their Terms: "RESTRICTIONS. General. You may not, nor may you permit others to:
ix: use the Services for the purpose of identifying or locating a specific individual or household."
So I wouldn't rely on them for this, as it is 'illegal?' or at least against thier policy.
Upvotes: 0
Reputation: 391
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System;
using UnityEngine.Networking;
using Newtonsoft.Json;
public class geoplugin
{
//Assume E.g. before each comment
public string geoplugin_request; //THIS IS THE IP ADDRESS
public int geoplugin_status; //200
public string geoplugin_delay; //"1ms"
public string geoplugin_credit;
public string geoplugin_city; //E.g Toronto.
public string geoplugin_region; //E.g. Ontario
public string geoplugin_regionCode; //E.g. ON
public string geoplugin_regionName; //Also Ontario
public string geoplugin_areaCode; //idk
public string geoplugin_dmaCode; //idk
public string geoplugin_countryCode; //E.g. CA (that's Canada)
public string geoplugin_countryName; //E.g. Canada
public int geoplugin_inEU; //0 if not in EU
public bool geoplugin_euVATrate; //false
public string geoplugin_continentCode; //E.g. NA
public string geoplugin_continentName; //North America
public string geoplugin_latitude;
public string geoplugin_longitude;
public string geoplugin_locationAccuracyRadius; //"1"
public string geoplugin_timezone; //"America\/Toronto",
public string geoplugin_currencyCode; //"CAD",
public string geoplugin_currencySymbol; //"$",
public string geoplugin_currencySymbol_UTF8; //$",
public float geoplugin_currencyConverter;
}
public class GetMyIP : MonoBehaviour
{
geoplugin geoInfo;
string ip;
public void GetIP()
{
StartCoroutine(GetRequest("http://www.geoplugin.net/json.gp", (UnityWebRequest req) =>
{
if (req.isNetworkError || req.isHttpError)
{
Debug.Log($"{req.error}: {req.downloadHandler.text}");
}
else
{
geoplugin geopluginData = JsonConvert.DeserializeObject<geoplugin>(req.downloadHandler.text);
ip = geopluginData.geoplugin_request;
geoInfo = geopluginData;
Debug.Log(ip);
//AT THIS POINT IN THE CODE YOU CAN DO WHATEVER YOU WANT WITH THE IP ADDRESS
}
}));
}
IEnumerator GetRequest(string endpoint, Action<UnityWebRequest> callback)
{
using (UnityWebRequest request = UnityWebRequest.Get(endpoint))
{
// Send the request and wait for a response
yield return request.SendWebRequest();
callback(request);
}
}
}
This should give you the ip address stored in the string ip
, which you can use for whatever you want. It's also possible that this will get you a lot of information that you needed the ip address for in the first place.
That was my experience anyways. I was trying to create an in game weather system that matched the real world weather, and I wanted the ip address to then find the location but this site provides both, removing the need to get the ip address first.
This is the tutorial I followed to figure out this code: https://theslidefactory.com/using-unitywebrequest-to-download-resources-in-unity/
You'll also need to import this for the code to work: https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347
If you just want the ip address and nothing else, then this is not the best solution. However, most of the time, you want to do something with the ip address, like get location, and this provides a lot of that stuff that you might be trying to get.
Upvotes: 0
Reputation: 31
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
public class TestLocationService : MonoBehaviour
{
public Text hintText;
private void Start()
{
GetLocalIPAddress();
}
public string GetLocalIPAddress()
{
var host = Dns.GetHostEntry(Dns.GetHostName());
foreach (var ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
hintText.text = ip.ToString();
return ip.ToString();
}
}
throw new System.Exception("No network adapters with an IPv4 address in the system!");
}
}
Upvotes: 3
Reputation: 5423
this is a minor modification to the excellent answer already provided by @Programmer. the motivation here is to improve functionality on MacOS and iOS. i haven't looked at android yet. i've also only tested IPV4.
what's different from @Programmer's original:
en0
, en1
). This option should obviously not be used if all you want is the IP address itself.public static class IPManager
{
public enum ADDRESSFAM
{
IPv4, IPv6
}
public static string GetIP(ADDRESSFAM Addfam)
{
string ret = "";
List<string> IPs = GetAllIPs(Addfam, false);
if (IPs.Count > 0) {
ret = IPs[IPs.Count - 1];
}
return ret;
}
public static List<string> GetAllIPs(ADDRESSFAM Addfam, bool includeDetails)
{
//Return null if ADDRESSFAM is Ipv6 but Os does not support it
if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
{
return null;
}
List<string> output = new List<string>();
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS
NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
bool isCandidate = (item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2);
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
// as of MacOS (10.13) and iOS (12.1), OperationalStatus seems to be always "Unknown".
isCandidate = isCandidate && item.OperationalStatus == OperationalStatus.Up;
#endif
if (isCandidate)
#endif
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
//IPv4
if (Addfam == ADDRESSFAM.IPv4)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
string s = ip.Address.ToString();
if (includeDetails) {
s += " " + item.Description.PadLeft(6) + item.NetworkInterfaceType.ToString().PadLeft(10);
}
output.Add(s);
}
}
//IPv6
else if (Addfam == ADDRESSFAM.IPv6)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
output.Add(ip.Address.ToString());
}
}
}
}
}
return output;
}
}
Upvotes: 1
Reputation: 12592
For 2018...
It does seem to be the case that you can now call - on the server, in NetworkManager - simply NetworkConnection#address
and it will give it to you.
Recall that you must write your own NetworkManager, it does not work out of the box. Explained here if yer new to unity networking:
public class OurNetworkManager : NetworkManager {
//
// server .............
//
public override void OnServerConnect(NetworkConnection nc) {
// it means "here on the server" one of the clients has connected
base.OnServerConnect(nc);
Log("a client connected " + nc.connectionId + " " + nc.hostId);
Log("address? " + nc.address);
}
public override void OnServerDisconnect(NetworkConnection nc) { .. etc
.
1) this only gives it to you on the server,
2) and only at "NetworkManager" which (of course!) is not actually when you identify each connecting client
Note the even newer answer - Unity finally resolved this.
Upvotes: 0
Reputation: 12592
Inside any [Command]
arriving on the server,
the IP of the client, which, sent the [Command]
is
connectionToClient.address
Phew.
You will in fact have your own NetworkBehaviour
derived class, you must do this. (It is very often called "Comms"):
public partial class Comms : NetworkBehaviour {
That class must override both the server/client startoffs, so that each Comms "knows what it is".
public override void OnStartServer() {
.. this "Comms" does know it IS the server ..
}
public override void OnStartLocalPlayer() {
.. this "Comms" does know it IS one of the clients ..
}
On any actual project, since Unity doesn't do it, the clients must identify themselves to the server. You have to entirely handle that in Unity networking, from scratch.
(Note. that process is explained in the long blog here
So this would be the first thing you (must) do in OnStartLocalPlayer
public override void OnStartLocalPlayer() {
Grid.commsLocalPlayer = this;
StandardCodeYouMustHave_IdentifySelfToServer();
// hundreds of other things to do..
// hundreds of other things to do..
}
That "command pair" inside comms would look like this:
You must do this in all networking projects (or you will have no clue which client is which):
public void StandardCodeYouMustHave_IdentifySelfToServer() {
string identityString = "quarterback" "linebacker" "johnny smith"
.. or whatever this device is ..
CmdIdentifySelfToServer( identityString );
// hundreds more lines of your code
// hundreds more lines of your code
}
[Command]
void CmdIdentifySelfToServer(string connectingClientIdString) {
.. you now know this connection is a "connectingClientIdString"
.. and Unity gives you the connection: in the property: connectionToClient
.. you must record this in a hash, database, or whatever you like
MakeANote( connectingClientIdString , connectionToClient )
// hundreds more lines of your code
// hundreds more lines of your code
}
The good news is Unity have added the connectionToClient
property, that is to say on the server, inside a [Command]
.
And then, you can indeed use the new .address
property on that.
public void StandardCodeYouMustHave_IdentifySelfToServer() {
CmdIdentifySelfToServer( identityString );
}
[Command]
void CmdIdentifySelfToServer(string connectingClientIdString) {
MakeANote( connectingClientIdString , connectionToClient )
string THEDAMNEDIP = connectionToClient.address;
}
It's that "simple", the ip of the client, which just connected, is "THEDAMNEDIP".
Phew.
Only took Unity 5? years.
Upvotes: 1
Reputation: 125245
The Network.player.ipAddress
has been deprecated since it is based on the old obsolete Unity networking system.
If you are using Unity's new uNet Network System, you can use NetworkManager.networkAddress
;
string IP = NetworkManager.singleton.networkAddress;
If you are using raw networking protocol and APIs like TCP/UDP, you have to use the NetworkInterface
API to find the IP Address. I use IPManager
which has been working for me on both desktop and mobile devices:
IPv4:
string ipv4 = IPManager.GetIP(ADDRESSFAM.IPv4);
IPv6:
string ipv6 = IPManager.GetIP(ADDRESSFAM.IPv6);
The IPManager
class:
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
public class IPManager
{
public static string GetIP(ADDRESSFAM Addfam)
{
//Return null if ADDRESSFAM is Ipv6 but Os does not support it
if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
{
return null;
}
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;
if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
#endif
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
//IPv4
if (Addfam == ADDRESSFAM.IPv4)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
//IPv6
else if (Addfam == ADDRESSFAM.IPv6)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
{
output = ip.Address.ToString();
}
}
}
}
}
return output;
}
}
public enum ADDRESSFAM
{
IPv4, IPv6
}
Upvotes: 15