This chapter describes the UDP model available in ns-3.
ns-3 supports a native implementation of UDP. It provides a connectionless, unreliable datagram packet service. Packets may be reordered or duplicated before they arrive. UDP calculates and checks checksums to catch transmission errors.
This implementation inherits from a few common header classes in the src/network directory, so that user code can swap out implementations with minimal changes to the scripts.
Here are the important abstract base classes:
This is an implementation of the User Datagram Protocol described in RFC 768. UDP uses a simple connectionless communication model with a minimum of protocol mechanism. The implementation provides checksums for data integrity, and port numbers for addressing different functions at the source and destination of the datagram. It has no handshaking dialogues, and thus exposes the user’s data to any unreliability of the underlying network. There is no guarantee of data delivery, ordering, or duplicate protection.
In many cases, usage of UDP is set at the application layer by telling the ns-3 application which kind of socket factory to use.
Using the helper functions defined in src/applications/helper, here is how one would create a UDP receiver:
// Create a packet sink on the receiver
uint16_t port = 50000;
Address sinkLocalAddress(InetSocketAddress (Ipv4Address::GetAny (), port));
PacketSinkHelper sinkHelper ("ns3::UdpSocketFactory", sinkLocalAddress);
ApplicationContainer sinkApp = sinkHelper.Install (serverNode);
sinkApp.Start (Seconds (1.0));
sinkApp.Stop (Seconds (10.0));
Similarly, the below snippet configures OnOffApplication traffic source to use UDP:
// Create the OnOff applications to send data to the UDP receiver
OnOffHelper clientHelper ("ns3::UdpSocketFactory", Address ());
clientHelper.SetAttribute ("Remote", remoteAddress);
ApplicationContainer clientApps = (clientHelper.Install (clientNode);
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (9.0));
For users who wish to have a pointer to the actual socket (so that socket operations like Bind(), setting socket options, etc. can be done on a per-socket basis), UDP sockets can be created by using the Socket::CreateSocket() method as given below:
Ptr<Node> node = CreateObject<Node> ();
InternetStackHelper internet;
internet.Install (node);
Ptr<SocketFactory> socketFactory = node->GetObject<UdpSocketFactory> ();
Ptr<Socket> socket = socketFactory->CreateSocket ();
socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), 80));
Once a UDP socket is created, we do not need an explicit connection setup before sending and receiving data. Being a connectionless protocol, all we need to do is to create a socket and bind it to a known port. For a client, simply create a socket and start sending data. The Bind() call allows an application to specify a port number and an address on the local machine. It allocates a local IPv4 endpoint for this socket.
At the end of data transmission, the socket is closed using the Socket::Close(). It returns a 0 on success and -1 on failure.
Please note that applications usually create the sockets automatically. Please refer to the source code of your preferred application to discover how and when it creates the socket.
The following is the description of the public interface of the UDP socket, and how the interface is used to interact with the socket itself.
Socket APIs for UDP connections:
Public callbacks
These callbacks are called by the UDP socket to notify the application of interesting events. We will refer to these with the protected name used in socket.h, but we will provide the API function to set the pointers to these callback as well.
The following test cases have been provided for UDP implementation in the src/internet/test/udp-test.cc file.