C# + .NET: Minimalistic asynchronous UDP example

Recently I have been experimenting with networking in Unity3d.
As you may know, there are various systems to aid you with building networked applications in Unity, ranging in approaches and capabilities.
However, if you are more familiar with the regular socket APIs, or just need to port a bit of existing code, you would probably rather have a couple of simple methods to send and receive data.
So here's just that, using .NET's System.Net.Sockets.UdpClient to asynchronously receive and handle data as it arrives:

using System;
using System.Net.Sockets;
using System.Net;
 
namespace UdpTest {
	class Program {
		static void OnUdpData(IAsyncResult result) {
			// this is what had been passed into BeginReceive as the second parameter:
			UdpClient socket = result.AsyncState as UdpClient;
			// points towards whoever had sent the message:
			IPEndPoint source = new IPEndPoint(0, 0);
			// get the actual message and fill out the source:
			byte[] message = socket.EndReceive(result, ref source);
			// do what you'd like with `message` here:
			Console.WriteLine("Got " + message.Length + " bytes from " + source);
			// schedule the next receive operation once reading is done:
			socket.BeginReceive(new AsyncCallback(OnUdpData), socket);
		}
		static void Main(string[] args) {
			UdpClient socket = new UdpClient(5394); // `new UdpClient()` to auto-pick port
			// schedule the first receive operation:
			socket.BeginReceive(new AsyncCallback(OnUdpData), socket);
			// sending data (for the sake of simplicity, back to ourselves):
			IPEndPoint target = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5394);
			// send a couple of sample messages:
 			for (int num = 1; num <= 3; num++) {
				byte[] message = new byte[num];
				socket.Send(message, message.Length, target);
			}
			Console.ReadKey();
		}
	}
}

Using this approach I was able to create a networking system in Unity that works both for P2P connections between game' instances and connecting to external servers.

Additional notes:

  • Sending in this example is synchronous, but has little to no effect (writing to a socket doesn't take long, moreso given the UDP datagram size limits).
  • AsyncResult.AsyncState can be any kind of object.
    In this example I'm using it to easily retrieve the socket that has received the data.
    For more complex systems, it can be a good idea to make a "context" class, which would contain the socket (UdpClient) and any other values that you may need.
  • Due to the current threading restrictions in Unity, you may not be able to access engine-related (unityengine.*) functionality from threads. To workaround this, push received messages into a list somewhere, and then handle them in the Update method of a MonoBehaviour.

Have fun!

Related posts:

3 thoughts on “C# + .NET: Minimalistic asynchronous UDP example

  1. You know, for the last few hours I felt like I’ve been banging my head against the wall trying to get my client and server talking via UDP. Your solution is so much easier than what I was working with!

    I had a Python client which was polling my game for the latest data, so the game was actually acting as the server in this case. Using your solution has worked a treat, so many thanks for sharing 🙂

  2. Hi ! Thanks for the code sample.
    About handling received data into a queue and dequeue it in some Update function, do you think that the best way is to treat a packet per frame or to process all the new packets at the next frame ?

    • Hello, you would usually process all available packets at the start of game frame to minimize latency. Occasionally games allow queuing up and distributing events (rather than packets themselves) to avoid everything happening at once after a lag spike, but this is not something you do with UDP, as the packets do not generally “buffer” like on TCP.

Leave a Reply

Your email address will not be published. Required fields are marked *