Click here to Skip to main content
15,860,859 members
Articles / Programming Languages / C#

Basic UDP Receiver

Rate me:
Please Sign up or sign in to vote.
4.59/5 (17 votes)
20 Jun 2013CPOL3 min read 155K   12K   57   23
A simple receiver for UDP packages sent by a transmitter.

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:

C#
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.

C#
// 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.

C#
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)


Written By
Engineer
Norway Norway
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Suggestionhex format Pin
Cviel Kadan3-Jan-22 7:53
Cviel Kadan3-Jan-22 7:53 
GeneralAnother way to learn UDP socket programming in C# .Net Pin
Naeem Akram26-May-19 8:16
professionalNaeem Akram26-May-19 8:16 
QuestionJust what I needed when I needed it. Pin
DavidDunning21-Oct-15 0:16
DavidDunning21-Oct-15 0:16 
QuestionCannot access a disposed object. Object name: 'System.Net.Sockets.UdpClient'. Pin
Mujtaba Faizan12-May-15 1:28
Mujtaba Faizan12-May-15 1:28 
SuggestionThanks Pin
desplus2-Dec-14 1:27
desplus2-Dec-14 1:27 
GeneralRe: Thanks Pin
Amund Gjersøe2-Dec-14 1:33
Amund Gjersøe2-Dec-14 1:33 
QuestionSteps to send message and Display received message Pin
VickTy26-Jun-14 2:53
VickTy26-Jun-14 2:53 
GeneralC++ code Pin
Member 1053261420-Jan-14 5:10
Member 1053261420-Jan-14 5:10 
SuggestionRe: C++ code Pin
Amund Gjersøe20-Jan-14 5:55
Amund Gjersøe20-Jan-14 5:55 
GeneralRe: C++ code Pin
Member 1053261421-Jan-14 9:52
Member 1053261421-Jan-14 9:52 
GeneralRe: C++ code Pin
learner198817-Jul-15 11:20
learner198817-Jul-15 11:20 
QuestionNice Article...How about data loss Pin
Madgant10-Apr-13 17:00
Madgant10-Apr-13 17:00 
Very nice article.
I was using same code to receive some ASCII data from alarm receiver.

In my case, application cannot receive data, because alarm receiver send some package to check "Monitoring"
and "Monitoring" should send "ACK" action and send package back to alarm receiver.

I have to consult this to my Alarm Receiver Vendor. They said : "Should use CRC (cyclic redundancy check)to check data loss.



How to do this

Regards,
___Mahmudk
AnswerRe: Nice Article...How about data loss Pin
Amund Gjersøe10-Apr-13 19:53
Amund Gjersøe10-Apr-13 19:53 
QuestionPerformance Pin
bertholdra5-Nov-12 12:44
bertholdra5-Nov-12 12:44 
SuggestionRe: Performance Pin
Amund Gjersøe5-Nov-12 20:33
Amund Gjersøe5-Nov-12 20:33 
GeneralGreat Pin
Vilbergo1-Aug-12 0:32
Vilbergo1-Aug-12 0:32 
GeneralThanks... Pin
Amund Gjersøe1-Aug-12 0:37
Amund Gjersøe1-Aug-12 0:37 
Questionudp server Pin
Nematatani Rofhiwa13-Mar-12 21:04
Nematatani Rofhiwa13-Mar-12 21:04 
GeneralUDP Sender.. Pin
yltsa14-Dec-10 0:05
yltsa14-Dec-10 0:05 
GeneralUDP vs TCP Pin
supercat910-Dec-10 12:34
supercat910-Dec-10 12:34 
GeneralIntrigued Pin
victorbos9-Dec-10 2:35
victorbos9-Dec-10 2:35 
GeneralRe: Intrigued Pin
Amund Gjersøe9-Dec-10 4:18
Amund Gjersøe9-Dec-10 4:18 
GeneralRe: Intrigued Pin
victorbos9-Dec-10 4:22
victorbos9-Dec-10 4:22 

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

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