The goal of this small demo project is to create 2 small UDP based programs which ping-pong each other every 500ms.

Visual Studio setup:

  • Create a new blank solution
  • Add a new c# console application for the server
  • Add a new c# console application for the client
  • Right-click your solution in Solution Explorer then click ‘Set Startup projects…’
  • Select ‘Multiple startup projects’ from the radio list
  • Set both actions to ‘Start’ and make sure your server project is first
class PingPongServer
{
    static void Main()
    {
        var server = new UdpClient(new IPEndPoint(IPAddress.Loopback, 30000));
        var childEndPoint = default(IPEndPoint);

        while (true)
        {
            _ = server.Receive(ref childEndPoint);
            Console.WriteLine("Received ping from {0}", childEndPoint);

            Console.WriteLine("Sending pong to {0}", childEndPoint);
            server.Send(Array.Empty<byte>(), 0, childEndPoint);
        }
    }
}

The server is bound to the loopback address (127.0.0.1) on port 30000 in the UdpClient constructor. It will listen for incoming packets on this address and port. The variable childEndPoint will be the address and port of the computer which sent the message.

The server then enters an infinite loop which starts by waiting to receive an empty packet from the client.

class PingPongClient
{
    static void Main()
    {
        var client = new UdpClient();
        var serverEndPoint = new IPEndPoint(IPAddress.Loopback, 30000);
        client.Connect(serverEndPoint);

        IPEndPoint remoteEndPoint = null;   // this will always be equal to serverEndPoint in our example
        while (true)
        {
            Console.WriteLine("Sending ping to server");
            client.Send(Array.Empty<byte>(), 0);

            Thread.Sleep(TimeSpan.FromMilliseconds(500));

            _ = client.Receive(ref remoteEndPoint);
            Console.WriteLine("Received pong from server");
        }
    }
}

The client is created using the empty UdpClient constructor, this sets the address to the loopback 127.0.0.1 and assigns a port dynamically. We know the server address and port number so we can use the UdpClient.Connect() method to establish a default destination when sending packets - as you can see from client.Send(Array.Empty<byte>(), 0) - no address or port were mentioned they were inferred from Connect()

The program then enters an infinite loop which starts by sending an empty packet to the server, waiting 500ms, then receiving the response. Going forward this is not the recommended approach as it blocks the thread while it waits to receive information from the server.