Click here to Skip to main content
Click here to Skip to main content

Basic UDP Receiver

By , 20 Jun 2013
Rate this:
Please Sign up or sign in to vote.

Introduction

As I am testing some equipment that sends data as UDP, I need to confirm that the data is actually received at the desired computer, and not blocked on the way.

When I searched the web, I did not find a really simple application that helps me. They were either hardcoded with a fixed port, or too complex. Thus, I decided to program one myself, and I would like to share it with you.

Summary

I have implemented this as a console application. It includes three switches to set the local port, remote port, and the remote IP. If data is received with the specified setting, the data is converted to ASCII and printed in the console.

SimpleUdpReceiver/Screenshot.png

The screen dump shows the result after I have started receiving data from an AIS-receiver that is set up to send data, using UDP, to an IP-range that covers my computer.

User Datagram Protocol

User Datagram Protocol (UDP) is a protocol for sending data on an IP-network. It is an alternative to the more commonly used Transmission Control Protocol (TCP). The major difference between the two, related to sending data, is that while TCP has handshaking, UDP has not. However, UDP is more efficient than TCP when sending the same data to multiple receivers.

Choosing between TCP and UDP is often an issue when streaming data over an Ethernet. If it is a point-to-point application, where for instance a sensor is sending data to a logging application, TCP would guarantee that all data is received at the logging side. If multiple clients would like the same guaranteed service, a more advanced TCP server-client code is needed. Then the data is transmitted once for each client, and you get more network traffic. If there are multiple clients that tolerate some data loss, due to lack of handshaking, you can implement the communication using UDP. If the clients only listen to the stream, then it is far easier to use UDP for distributing one stream to many clients than using TCP, implementation wise.

There are many thoughts about UDP vs. TCP, but this is a quick summary of mine.

Using the code

I've already mentioned that this is a simple application, and the following code sections will confirm this. The code does not include any exception handling or other hints to why data is not received.

Setting the properties through switches

The properties are set at startup through switches. As an example: SimpleUdpReceiver -lp 1234 sets the local port to 1234. The code behind is a regular input argument switch:

for( int i = 0; i < args.Length; i++)
{
    string cmd = args[i];  // The current command switch
    string value; // The current value related to the command
    int tempInt;  // Temporary integer holder
    IPAddress tempAddress; // Temporary ip holder
                
    switch (cmd)
    {
        case "-lp": // Local port
            value = GetValue(args, ref i);
            if (int.TryParse(value, out tempInt))
                localPort = tempInt;
            break;
        case "-rp": // Remote port
            value = GetValue(args, ref i);
            if (int.TryParse(value, out tempInt))
                remoteSender.Port = tempInt;
            break;
        case "-rh": // Remote ip
            value = GetValue(args, ref i);
            if (IPAddress.TryParse(value, out tempAddress))
                remoteSender.Address = tempAddress;
            else if (int.TryParse(value, out tempInt) && tempInt == 0)
                remoteSender.Address = IPAddress.Any;
            break;
        case "-?":  // Help text
        default:
            PrintHelpText();
            flag = true;
            break;
    }
}

If some of the switches are wrong, the switch-statement defaults, and the applications terminate displaying the help text. If some of the values are not parsed, the default value is used.

Start receiving UDP packages

Using the UdpClient, my job of implementing UDP is greatly simplified. The client is created using the set local port. Then the client and information of the remote endpoint is stored in the class UdpState. UdpState is just a container for the two variables, and copied from the help sites from Microsoft.

// Create UDP client
UdpClient client = new UdpClient(localPort);
UdpState state = new UdpState(client, remoteSender);
// Start async receiving
client.BeginReceive(new AsyncCallback(DataReceived), state);

// Wait for any key to terminate application
Console.ReadKey();
client.Close();

Handling received UDP packages

UdpClient receives data asynchronized when using BeginReceive(). The method DataReceived runs in the thread pool to handle incoming UPD packages.

private static void DataReceived(IAsyncResult ar)
{
    UdpClient c = (UdpClient)((UdpState)ar.AsyncState).c;
    IPEndPoint wantedIpEndPoint = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
    IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
    Byte[] receiveBytes = c.EndReceive(ar, ref receivedIpEndPoint);

    // Check sender
    bool isRightHost = (wantedIpEndPoint.Address.Equals(receivedIpEndPoint.Address) 
                       || wantedIpEndPoint.Address.Equals(IPAddress.Any);
    bool isRightPort = (wantedIpEndPoint.Port == receivedIpEndPoint.Port)
                       || wantedIpEndPoint.Port == 0;
    if (isRightHost && isRightPort)
    {
        // Convert data to ASCII and print in console
        string receivedText = ASCIIEncoding.ASCII.GetString(receiveBytes);
        Console.Write(receivedText);
    }

    // Restart listening for udp data packages
    c.BeginReceive(new AsyncCallback(DataReceived), ar.AsyncState);
}

Points of Interest

UDP as a protocol is like "fire and forget", so I used Wireshark to check how many UDP packages I received with wrong checksum. And on the LAN I am connected to, with some 100 clients, I got a ~4% bad checksum rate when sending a package every second or so. Normally, I use TCP to transmit sensor data, but in some cases, I have receivers which need UDP and accepts that some data may not be received.

Often corporate firewalls stop UDP packages receiving the endpoint. But it may also be that the local port is in other use, causing conflict when trying to receive packages.

Update 

June 20th 2013 - It occurred to me that c.EndReceive(ar, ref ipEndPoint) don't filter incoming broadcast to the specified endpoint. Thus, I have now added a test to confirm that the data is received from the host specified. 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Amund Gjersøe
Engineer
Norway Norway
No Biography provided

Comments and Discussions

 
GeneralIntrigued Pinmembervictorbos9-Dec-10 2:35 
GeneralRe: Intrigued PinmemberAmund9-Dec-10 4:18 
GeneralRe: Intrigued Pinmembervictorbos9-Dec-10 4:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 20 Jun 2013
Article Copyright 2010 by Amund Gjersøe
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid