Academic Company Events NI Developer Zone Support Solutions Products & Services Contact NI MyNI

Document Type: Tutorial
NI Supported: Yes
Publish Date: Jan 22, 2009


Feedback


Yes No

Related Categories

Related Links - Developer Zone

Related Links - Products and Services

Building Networked Applications with the LabWindows™/CVI UDP Support Library

4 ratings | 4.50 out of 5
Read in | Print | PDF

Overview

This technical white paper provides an overview of the UDP Support Library available in NI LabWindows/CVI Version 8.5 and later, including typical use cases, comparisons to other common communication protocols, and example code.

Introduction

Transmission Control Protocol (TCP), one of the core protocols of the Internet Protocol (IP) suite, currently accounts for approximately 75 percent of all Internet traffic. While TCP is the better known and more often used protocol within the transport layer of the IP suite, User Datagram Protocol (UDP) – sometimes referred to as Universal Datagram Protocol – accounts for nearly 20 percent of all Internet traffic.

TCP/IP Architecture Model

Figure 1. The Five-Layer TCP/IP Architecture Model

Depending on the use case, UDP can provide a more efficient design alternative for your networking applications. By using LabWindows/CVI UDP Support Library functions, you can create an easy interface to the three communication options that UDP has to offer: unicast, broadcast, and multicast messaging.  

What Is UDP?

UDP is a minimal message-oriented transport layer that uses ports to provide packet-switched application-to-application communication over a network. UDP encapsulates messages – or packets – in the form of a datagram (see Figure 2).


[+] Enlarge Image

Figure 2. A Typical UDP Datagram

A datagram is logically arranged in two parts – the datagram header and message. Each datagram header is further broken down into four sections, as illustrated in Figure 2. The minimum length of a single UDP datagram is the size of the datagram header, or 8 bytes. UDP is characterized by this minimal overhead and small packet size, which translates to higher throughput when compared to TCP. However, because inherent error checking and the guarantee of data receipt are sacrificed to achieve increased throughput, TCP becomes the more beneficial choice in applications where large message size or transmission reliability is important.

Protocol Differences

While TCP, UDP, and the NI Publish-Subscribe Protocol (NI-PSP), which is used in LabWindows/CVI network variables, are cross-platform communication protocols, there are important differences that help define when you should use each protocol in an application.

A Protocol Comparison Chart

Figure 3. A Comparison of Common Communication Protocols

Read More: Network Variable Technical Overview

Connectionless Communication 

TCP is a connection-based protocol. By establishing a connection between a server and a client, TCP servers and clients are able to communicate in such a way that data is guaranteed to arrive and messages are guaranteed to arrive in order. Should a message fail to arrive or arrive out of order, the TCP client exchanges information with the server that stops further packet exchange until the appropriate packet arrives or the connection experiences a timeout. To establish a connection, TCP requires a minimum exchange of three packets of information before the receipt of a response. UDP communication, on the other hand, requires only half as many data exchanges to receive a response. However, because UDP has no inherent flow control and reliability built into the overhead of its datagrams, it is up to the application developer to implement it, should error checking be necessary.


[+] Enlarge Image

Figure 4. UDP versus TCP Request/Response Models

Given the decrease in the number of exchanges required for communication under the UDP protocol, the server is spared the resources required to provide a TCP connection, which allows it to process more requests. 

Increased Throughput

As previously mentioned, UDP makes no attempt to control or guarantee the order in which datagrams arrive. Furthermore, UDP does not regulate transmission speeds based on network congestion. If network traffic causes the loss of a packet, UDP does nothing to resolve the issue; rather, UDP dictates that the application developer includes code that detects and resolves the situation. In contrast, TCP interprets packet loss as a sign of network congestion, even if no such congestion exists. As a result, TCP slows the outgoing data rate over a connection. On networks with high packet loss, this can result in significantly reduced transmission speeds under TCP, thereby drastically decreasing throughput. 

Comparable throughput decreases exist under TCP communication in the case of out-of-order packets. When an out-of-order packet is received, TCP forces all data processing to wait until the appropriately sequenced packet arrives, further decreasing efficiency in the event of packet loss. UDP, which makes no such regulation, is ideal in applications that can transmit large amounts of data and can afford some packet loss, especially if an alternative packet-loss recovery mechanism can be implemented.

Broadcast and Multicast Support

One critical benefit of UDP is the built-in broadcasting and multicasting functionality. While TCP – a connection-based protocol – requires a session to be maintained in order to communicate, UDP communication works by simply multiplexing messages based on port numbers contained within the “destination port” field of the datagram header. 

Unicast

Communication with a single client is called unicast.

Broadcast

Use UDP broadcast to communicate with all computers on a Local Area Network (LAN) or a specific subnet. If you want to communicate with multiple specific computers, you must configure the UDP functions to iterate through a list of clients. Using this technique creates duplicate network traffic because LabWindows/CVI sends a separate copy of the data to each client and maintains a list of clients interested in receiving the data.

Multicast

Use UDP multicast to communicate between a single sender and multiple clients on a network without requiring the sender to maintain a list of clients or send multiple copies of the data to each client. To receive data from a multicast sender, all clients must join a multicast group. The sender does not have to join a group to send data. The sender specifies a multicast IP address, which defines a multicast group. Multicast IP addresses are in the 224.0.0.0 to 239.255.255.255 range. When a client wants to join a multicast group, it subscribes to the multicast IP address of the group. After subscribing to a multicast group, the client receives data sent to the multicast IP address.

When to Use UDP

The choice of protocol should be done on a case-by-case basis, depending on application requirements. TCP communication is inherently more reliable than UDP, as TCP manages message acknowledgement (handshaking) and retransmission in the case of lost or out-of-order packets. Inclusion of such measures in TCP adds more overhead, as TCP requires three packet exchanges to initialize a socket connection. Furthermore, TCP adds extra latency when guaranteeing that messages arrive in order by preventing processing on data received out of order until missing packets arrive. By including the ability to broadcast and multicast messages, UDP further increases throughput by having to process each datagram only one time to send the message to multiple listeners.

Though sacrificing reliability within a communication protocol may seem like a high price to pay for increased throughput, not all applications require every data packet to arrive at its destination in order. In test applications, UDP is best suited for fast transmission of redundant data or applications that would benefit from the broadcast of information to multiple machines. In general, network applications that need faster processing time and have very small data units to exchange (and therefore very little sorting and sequencing to do) are good candidates for UDP instead of TCP.

 Benefits

 Use Cases

  •  5X smaller packet sizes than TCP
  •  Large amount of data transfer with acceptable data loss
  •  Less network traffic
  •  Fast data streaming
  •  Broadcast and multicast support
  •  Reduction of network connections

 

LabWindows/CVI UDP Support Library

The LabWindows/CVI UDP Support Library, introduced in LabWindows/CVI 8.5, provides built-in functions for transferring data over UDP. 

UDP Support Library Functions

Figure 5. LabWindows/CVI UDP Support Library Functions

The LabWindows/CVI UDP Support Library delivers easy-to-use functions to create UDP writer and reader applications. A single callback function offers the mechanism for receiving notification of data availability. The LabWindows/CVI UDP Support Library calls the server and client program callback functions when the following UDP event occurs:

  • UDP_DATAREADY

The paradigm for creating UDP writers and readers is as follows: 


[+] Enlarge Image

Figure 6. UDP Writer and Reader Program Flow

Programs using LabWindows/CVI UDP functions depend on the LabWindows/CVI UDP Support Library, which is part of the LabWindows/CVI Run-Time Engine. The LabWindows/CVI UDP Support Library uses the Windows Sockets (Winsock) API. Winsock provides direct access to services in the transport layer within the TCP/IP architecture model (see Figure 1).

UDP Writer Example

The following example sets up an application that writes data via UDP. Before running, uncomment the portion of the code that represents your chosen method of UDP communication.

 

#include <ansi_c.h>
#include <cvirte.h>    
#include <userint.h>
#include <udpsupp.h>
#include "toolbox.h"
#include "UDPWriter.h"
#include "UDPReaderWriterCommon.h"

#define MAX_DATA_INPUT_LENGTH   100
#define MAX_IP_INPUT_LENGTH     20

static int panelHandle;
static int writerChannel = 0;

int main (int argc, char *argv[])
{

    int error = 0;
   
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((panelHandle = LoadPanel (0, "UDPWriter.uir", PANEL)) < 0)
        return -1;
   
    // Initialize some additional UI settings.
    errChk (SetCtrlAttribute(panelHandle, PANEL_DATA, ATTR_MAX_ENTRY_LENGTH, MAX_DATA_INPUT_LENGTH));
    errChk (SetCtrlAttribute(panelHandle, PANEL_ADDR, ATTR_MAX_ENTRY_LENGTH, MAX_IP_INPUT_LENGTH));
   
    // Create a UDP channel from which to send messages. The port number can be any available
    // port since we expect only to write, not receive data.
    errChk (CreateUDPChannel(UDP_ANY_LOCAL_PORT, &writerChannel));
   
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
Error:
    if (writerChannel)
        DisposeUDPChannel(writerChannel);
    if (error < 0)
        MessagePopup("Error", GetGeneralErrorString(error));
    return 0;

}

int CVICALLBACK Send (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{

    int error = 0;
   
    if (event == EVENT_COMMIT)
    {
        char data[MAX_DATA_INPUT_LENGTH + 1];
        char destAddr[MAX_IP_INPUT_LENGTH + 1] = "0";
       
        errChk (GetCtrlVal(panel, PANEL_DATA, data));  
       
        // Depending on which communication method is desired, the message is addressed to one of:
        //  (1) a specific IP address or DNS-resolvable host name (Unicast),
        //  errChk (GetCtrlVal(panel, PANEL_ADDR, destAddr));
       
        //  (2) a predetermined multicast address to which multiple readers may be subscribed (Multicast),
        //  errChk (GetCtrlVal(panel, PANEL_ADDR, destAddr));
       
        //  (3) the broadcast address, which propagates to every computer on the subnet (Broadcast).
        //  strcpy(destAddr, UDP_LAN_BROADCAST_ADDR);
  
        // Write the message to a predetermined port number on which all readers will listening.
        errChk (UDPWrite(writerChannel, READER_PORT, destAddr, data, strlen(data) + 1));
    }
Error:
    if (error < 0)
        MessagePopup("Error", GetGeneralErrorString(error));
    return 0;

}

int CVICALLBACK PanelCallback (int panel, int event, void *callbackData,
        int eventData1, int eventData2)
{

    if (event == EVENT_CLOSE)
        QuitUserInterface (0);
    return 0;

}

Download UDP Writer Example Code

UDP Reader Example

The following code sets up an application that reads data that has been transmitted via UDP.

 

#include <cvirte.h>    
#include <userint.h>
#include <udpsupp.h>
#include "toolbox.h"
#include "UDPReader.h"
#include "UDPReaderWriterCommon.h"

static int panelHandle;
static int readerChannel = 0;

int CVICALLBACK UDPCallback (unsigned channel, int eventType, int errCode, void *callbackData);

int main (int argc, char *argv[])
{

    int error = 0;
   
    if (InitCVIRTE (0, argv, 0) == 0)
        return -1;  /* out of memory */
    if ((panelHandle = LoadPanel (0, "UDPReader.uir", PANEL)) < 0)
        return -1;
   
    errChk (SetCtrlVal(panelHandle, PANEL_MULTICAST_IP, MULTICAST_ADDRESS));
       
    errChk (CreateUDPChannelConfig(READER_PORT, UDP_ANY_ADDRESS, 0, UDPCallback, NULL, &readerChannel));
   
    DisplayPanel (panelHandle);
    RunUserInterface ();
    DiscardPanel (panelHandle);
Error:
    if (readerChannel)
        DisposeUDPChannel (readerChannel);
    if (error < 0)
        MessagePopup("Error", GetGeneralErrorString(error));
    return 0;

}

int CVICALLBACK UDPCallback (unsigned channel, int eventType, int errCode, void *callbackData)
{
   

    int             error = 0,
                     size;
    unsigned char   *msg = NULL;
   
    if (eventType == UDP_DATAREADY)
    {
        char            srcAddr[16];
        unsigned int    srcPort;
        char            msgSourceString[16 + 10];
       
        // Pass NULL as the input buffer to determine the size of the arrived data.
        errChk (size = UDPRead(channel, NULL, 0, UDP_DO_NOT_WAIT, NULL, NULL));
       
        nullChk (msg = malloc(size));
       
        // Read the waiting message into the allocated buffer.
        < strong > errChk (size = UDPRead(channel, msg, size, UDP_DO_NOT_WAIT, &srcPort, srcAddr));
       
        // Display the message, preceded by the sender's IP address and port number.
        sprintf(msgSourceString, "[%s:%d]: ", srcAddr, srcPort);
        errChk (SetCtrlVal(panelHandle, PANEL_TEXTBOX, msgSourceString));
        errChk (SetCtrlVal(panelHandle, PANEL_TEXTBOX, msg));
        errChk (SetCtrlVal(panelHandle, PANEL_TEXTBOX, "\n"));
    }
Error:                                                            
    if (error < 0)
        MessagePopup("Error", GetGeneralErrorString(error));;
    if (msg)
        free(msg);
    return 0;

}

int CVICALLBACK DoMulticast (int panel, int control, int event,
        void *callbackData, int eventData1, int eventData2)
{
   

int error = 0;
   
    if (event == EVENT_COMMIT)
    {
        int on;
        char ipAddr[16];
       
        errChk (GetCtrlVal(panel, control, &on));
        errChk (GetCtrlVal(panel, PANEL_MULTICAST_IP, ipAddr));
       
        if (on)
            errChk (UDPMulticastSubscribe(readerChannel, ipAddr, NULL));
        else
            errChk (UDPMulticastUnsubscribe(readerChannel, ipAddr, NULL));
    }
Error:
    if (error < 0)
        MessagePopup("Error", GetGeneralErrorString(error));
    return 0;

}

int CVICALLBACK PanelCallback (int panel, int event, void *callbackData,
        int eventData1, int eventData2)
{
   

if (event == EVENT_CLOSE)
        QuitUserInterface (0);
    return 0;

}

Download UDP Reader Example Code

Error Handling

If an error condition occurs during a call to any of the functions in the LabWindows/CVI UDP Support Library, the status return value contains the error code. This code is a negative value that specifies the type of error that occurred.

You can call the GetUDPErrorString function to obtain a system message that describes the error. The system messages can be more descriptive than the UDP Support Library error codes. To obtain the correct system error message, you must call GetUDPErrorString immediately after calling the UDP Support Library function that failed.

For UDPRead and UDPWrite, the return value indicates the number of bytes transferred if the functions were successful.

Using the UDP Support Library in the LabWindows/CVI Real-Time Module

You can use LabWindows/CVI Real-Time to create ANSI C applications that run on real-time embedded targets. The LabWindows/CVI UDP Support Library is compatible with LabWindows/CVI Real-Time Module versions 8.5 and later, except for the multicasting functions, UDPMulticastSubscribe and UDPMulticastUnsubscribe

However, the LabWindows/CVI User Interface Library is not compatible with these targets. Therefore, you cannot call RunUserInterface to process messages and UDP events - ProcessSystemEvents should be used to handle callback events for UDP communication.

Multithreading

The LabWindows/CVI UDP Support Library is multithread-safe. In many applications, it makes sense to separate the UDP tasks from other tasks, such as user interface management, by running the different tasks in different threads. You can design UDP writers that multiplex messages to multiple listeners simultaneously to process each listener in a separate thread. In general, you should avoid doing time-consuming tasks inside a UDP callback because it can block other UDP or user interface events from being processed. Your callbacks can create separate threads to perform the time-consuming tasks, which leaves the main program thread free to continue processing events. When designing multithreaded UDP programs, note that the UDP callback function is called in the same thread that created the UDP channel.

Conclusion

UDP can provide many advantages over TCP communication, depending on the application in question. The decision regarding whether to select UDP or TCP as your communication protocol comes down to speed versus reliability. With LabWindows/CVI, you have built-in support for the most commonly used network protocols, such as TCP, Network Variables, and now UDP, which gives you the flexibility to choose which protocol is right for your application. 

Additional Resources

Try the LabWindows/CVI 8.5 Interactive Demo
Run the Example Code in the LabWindows/CVI 8.5 30-Day Evaluation
Subscribe to the LabWindows/CVI Developer Newsletter
View the LabWindows/CVI Resource Page

 

The mark LabWindows is used under a license from Microsoft Corporation.

Downloads

simple_udp_writer.zip

simple_udp_reader.zip

4 ratings | 4.50 out of 5
Read in | Print | PDF

Reader Comments | Submit a comment »

 

Legal
This tutorial (this "tutorial") was developed by National Instruments ("NI"). Although technical support of this tutorial may be made available by National Instruments, the content in this tutorial may not be completely tested and verified, and NI does not guarantee its quality in any way or that NI will continue to support this content with each new revision of related products and drivers. THIS TUTORIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND AND SUBJECT TO CERTAIN RESTRICTIONS AS MORE SPECIFICALLY SET FORTH IN NI.COM'S TERMS OF USE (http://ni.com/legal/termsofuse/unitedstates/us/).