Note to self: the .NET libraries in Unity are far behind the .NET libraries that appear on your computer. Many of the inscrutable errors I’ve run into while working in Unity, particularly in interprocess communication, can be traced to this.
This can be really deceptive, especially if you edit your scripts in Visual Studio. Since Visual Studio links up to the newest .NET libraries available on your computer, even if you run your code flawlessly in Visual Studio, it may not work like it should inside of Unity.
Today I was trying to communicate with Unity using Sockets. I had a server script in Unity, and a client script in a normal C# command line project. I knew it should be asynchronous since Unity is by nature single-threaded. I took out that semaphore control and the infinite loop in the server script so it’d be Unity compatible and not do a blocking wait for every incoming message. But it still didn’t work!
After much pain and suffering, I finally thought to check to see if the IP addresses and network types were matching between the two programs. I had the same three lines of code in both client and server:
IPHostEntry ipHostInfo = Dns.GetHostEntry("localhost"); IPAddress ipAddress = ipHostInfo.AddressList; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 80);
But when I printed out the IP address and the address types, the pure C# console program showed an IPv6 address, while the Unity program showed an IPv4 address. And that difference makes them not connect up right–since the server is listening for an IPv4 connection, it won’t pick up an IPv6 connection.
Thanks to this lovely StackOverflow answer, the simple solution on both ends is as follows:
IPAddress ipv4Addresses = Array.FindAll( Dns.GetHostEntry(string.Empty).AddressList, a => a.AddressFamily == AddressFamily.InterNetwork);
Maybe this saves someone else some time…or will save future-me some time one day!