.NET Documentation

Library Reference

UdpClient - Sending and Receiving Datagrams

The UdpClient class provides a simple way to send and receive datagrams using the User Datagram Protocol (UDP). UDP is a connectionless protocol, meaning that datagrams are sent independently and are not guaranteed to arrive in order, or even arrive at all. This makes UDP suitable for applications where low latency is more important than guaranteed delivery, such as streaming media or online gaming.

Core Concepts

Sending Data

To send data using UdpClient, you need to specify the target endpoint (IP address and port). The SendAsync method is used for asynchronous sending, which is the recommended approach to avoid blocking the application's thread.

SendAsync Method

The SendAsync method sends a UDP datagram to a specific remote host and port.


public Task SendAsync(byte[] datagram, int bytes, IPEndPoint remoteEP);
public Task SendAsync(byte[] datagram, int bytes, string hostname, int port);
            

Receiving Data

To receive data, you first bind the UdpClient to a local port. Then, you can use methods like ReceiveAsync to wait for incoming datagrams.

ReceiveAsync Method

The ReceiveAsync method asynchronously receives a UDP datagram from a remote host.


public Task ReceiveAsync();
            

The UdpReceiveResult object contains:

Example: Basic UDP Communication

This example demonstrates a simple client and server setup using UdpClient.

Server (Listening for messages)


using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

public class UdpServer
{
    public static async Task StartServerAsync(int port)
    {
        using (var udpClient = new UdpClient(port))
        {
            Console.WriteLine($"UDP Server started on port {port}. Listening for messages...");

            while (true)
            {
                try
                {
                    UdpReceiveResult result = await udpClient.ReceiveAsync();
                    string message = Encoding.ASCII.GetString(result.Buffer, 0, result.BytesTransferred);
                    Console.WriteLine($"Received from {result.RemoteEndPoint}: {message}");

                    // Echo back
                    byte[] responseData = Encoding.ASCII.GetBytes($"Echo: {message}");
                    await udpClient.SendAsync(responseData, responseData.Length, result.RemoteEndPoint);
                    Console.WriteLine($"Sent echo to {result.RemoteEndPoint}");
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error receiving or sending: {ex.Message}");
                }
            }
        }
    }
}
            

Client (Sending messages)


using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

public class UdpClientExample
{
    public static async Task SendMessageAsync(string serverIp, int serverPort, string message)
    {
        using (var udpClient = new UdpClient())
        {
            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);
            byte[] messageBytes = Encoding.ASCII.GetBytes(message);

            Console.WriteLine($"Sending '{message}' to {serverEndPoint}...");
            int bytesSent = await udpClient.SendAsync(messageBytes, messageBytes.Length, serverEndPoint);
            Console.WriteLine($"Sent {bytesSent} bytes.");

            // Optional: Receive echo
            try
            {
                var receiveTask = udpClient.ReceiveAsync();
                var timeoutTask = Task.Delay(5000); // 5 second timeout

                var completedTask = await Task.WhenAny(receiveTask, timeoutTask);

                if (completedTask == receiveTask)
                {
                    UdpReceiveResult result = await receiveTask;
                    string response = Encoding.ASCII.GetString(result.Buffer, 0, result.BytesTransferred);
                    Console.WriteLine($"Received echo: {response} from {result.RemoteEndPoint}");
                }
                else
                {
                    Console.WriteLine("Timeout waiting for echo.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error receiving echo: {ex.Message}");
            }
        }
    }
}
            

Important Considerations

Reliability

UDP does not provide any guarantee of delivery, order, or duplicate protection. If reliability is critical, consider using TCP or implementing your own reliability mechanisms on top of UDP.

Firewalls

Ensure that firewalls on both the sending and receiving machines allow UDP traffic on the specified ports.

Buffer Sizes

Be mindful of maximum UDP datagram sizes (typically around 65,507 bytes, but often limited by network infrastructure to 8,192 bytes or less). Large datagrams may be fragmented or dropped.