Socket SendTo throws Exception

Hello, I am trying to create a multiplayer game. I want to use my own networking solution using Sockets. However, whenever I try to use Socket.SendTo, I get the follwing exception: SocketException: The system detected an invalid pointer address in attempting to use a pointer argument in a call.

My code looks as follows:

IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), NetworkConfig.MASTER_SERVER_PORT);

 byte[] DataBuffer = new byte[3];
 byte[] portBytes = BitConverter.GetBytes(24061);
 DataBuffer[0] = portBytes[0];
 DataBuffer[1] = portBytes[1];
 DataBuffer[2] = 0;

 Socket SendSocket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);
 SendSocket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);

 SendSocket.SendTo(DataBuffer, ep);

When I use the exact same code in a console project, I do not get this error. The same thing happens when I call Socket.ReceiveFrom (but not when I call Socket.Receive interestingly).
Am I doing something wrong? Or is this a unity bug?

Thanks in advance!

I’m not that IPv6 savvy yet, but I don’t think you should mix an IPv4 address with an IPv6 socket. You may try using IPAddress.Parse("::1") instead in order to connect to local host.

ps: Is there a reason why you’re messing around with a raw socket manually? C# has the UdpClient class which wraps a Socket and helps initializing the socket and implements many safety checks, especially address family related ones. Microsoft provided the reference source if you want to know what the class actually does. Those dedicated classes usually makes the usage a lot easier.

Wow, that actually seems to have done the trick, thank you so much!

It does seem to be a bit weirder though, because at another point in the code I do basically the same thing (again, with an Ipv4 address) and it works just fine but only some of the time. Usually the IPv6Only-option should have made it so it doesn’t matter if you’re connecting to an IPv4 or IPv6 address, but for whatever reason this doesn’t seem to work properly with Unity (at least not all the time).
Interestingly, it does seem to work if you call Socket.Connect(EndPoint) first and then just use Socket.Send to send data.

Yes, I originally wanted to include TCP (and UDP) Hole Punching in my solution, but ran into problems when using the TcpClient. Then I experimented around with raw Sockets and got it working pretty quickly, so I just stuck with it

Well, it seems that there are some implementation differences between Microsoft’s .NET implementation and Mono’s implementation. Both have a method called “RemapIPEndPoint” which will remap an IPv4 address to an IPv6 address. Those are buried deep inside several methods. However it seems that Mono does call this method when you call Connect, but doesn’t call it when you use SendTo. The MS implementation does do the remapping in their “CheckCacheRemote” method which the mono implementation doesn’t even have.

Even though there is this remapping, you should just use the right address to begin with :). Even though IPv6 addresses are usually quite a bit longer and cumbersome to work with, the local host address ( "::1" ) is actually shorter thanks to the short form. Otherwise it would be "0000:0000:0000:0000:0000:0000:0000:0001"

You’ll be better off using one of the available “transport” protocols, be it Unity Transport or something other. This is still very low-level but it does provide you with a tried and proven framework so you won’t have to stumble into all sorts of oddities and quirks as that you you were just having after writing just the first few lines of code.

Trust me, it will continue to go on like this for a couple more weeks, if not months. There’s a lot more required than just being able to send data over sockets between two or more machines. Who is client? Who is server? Owner? Authority? Send to specific clients. Compress sent data. Update rate (ticks). Synching time. And a gazillion more things.

At the very least look at the code of a Transport and see all the things you would very likely have to implement yourself. You might be surprised. :wink:

That makes a lot of sense. I didn’t really look too deep into it as I assumed their implementations would be similar enough. Turns out I was very wrong. Thank you so much for looking into it! ^^

Yes, I totally agree. That was a silly mistake that I should have caught

Generally I would agree with you, however my solution is actually already pretty much finished. It was originally written (and also used by me) for applications outside of Unity and that snippet I provided was just some code I quickly wrote for my Unity use-case to quickly get a multiplayer prototype working. It has already seen quite a bit of testing and usage and seems to generally work pretty well… Well with Microsoft’s implementation of .NET that is : D
I was just worried that Unity for some reason didn’t support my solution and thus asked this question.

I know, you’re totally right on this. Luckily pretty much all of the relevant questions are already answered in my case, so I should be good. But thank you for your advice :slight_smile: