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.
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.
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]; string value; int tempInt; IPAddress tempAddress;
case "-lp": value = GetValue(args, ref i);
if (int.TryParse(value, out tempInt))
localPort = tempInt;
case "-rp": value = GetValue(args, ref i);
if (int.TryParse(value, out tempInt))
remoteSender.Port = tempInt;
case "-rh": 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;
case "-?": default:
flag = true;
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
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 is just a container for the two variables, and copied from the help sites from Microsoft.
UdpClient client = new UdpClient(localPort);
UdpState state = new UdpState(client, remoteSender);
client.BeginReceive(new AsyncCallback(DataReceived), state);
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);
bool isRightHost = (wantedIpEndPoint.Address.Equals(receivedIpEndPoint.Address)
bool isRightPort = (wantedIpEndPoint.Port == receivedIpEndPoint.Port)
|| wantedIpEndPoint.Port == 0;
if (isRightHost && isRightPort)
string receivedText = ASCIIEncoding.ASCII.GetString(receiveBytes);
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.
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.