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.
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.
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
}
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
https://forum.unity.com/threads/networkmanager-error-server-client-disconnect-error-1.439245/#post-3754939 )
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.
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:
https://forum.unity.com/threads/networkmanager-error-server-client-disconnect-error-1.439245/#post-3754939
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.
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;
}
}