Skip to the content.

< Previous: Basic Usage | 🏠 Home | Next: Performance Metrics >


Advanced Usage (Client & Multicast)

cpp-udpnet provides the UdpSender class for scenarios where you need to actively send datagrams (e.g., as a client) or participate in multicast groups.

Using UdpSender (Client)

A typical client binds to a local port to receive responses and uses Send to transmit data to a server.

#include "cppudpnet.hpp"
#include <iostream>
#include <string>

int main() {
    cppudpnet::UdpSender client;

    // Bind to a local port to receive responses (optional, but needed if you expect replies)
    // Binding to `0` allows the OS to assign an ephemeral port dynamically.
    client.Bind(0);
    uint16_t assigned_port = client.GetLocalPort();

    client.SetDataHandler([](const cppudpnet::PeerAddress& peer,
                             const std::vector<uint8_t>& data) {
        std::string text(data.begin(), data.end());
        std::cout << "Response from " << peer.ToString() << ": " << text << std::endl;
    });

    try {
        client.Start();

        client.Send("127.0.0.1", 8080, "Hello UDP Server!");
        std::cout << "Sent message. Press Enter to exit." << std::endl;
        std::cin.get();

        client.Stop();
    } catch (const std::exception& e) {
        std::cerr << "Failed: " << e.what() << std::endl;
    }

    return 0;
}

Multicast Support

cpp-udpnet makes it trivial to join and leave multicast groups. Multicast allows a single datagram to be received by multiple hosts.

Multicast Sender

To send multicast datagrams, you simply send to the multicast group address (e.g., 239.255.0.1).

#include "cppudpnet.hpp"
#include <iostream>
#include <string>
#include <thread>
#include <chrono>

int main() {
    cppudpnet::UdpSender sender;

    try {
        sender.Start();

        for (int i = 0; i < 10; ++i) {
            std::string message = "Multicast message #" + std::to_string(i + 1);
            sender.Send("239.255.0.1", 9000, message);
            std::cout << "Sent: " << message << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }

        sender.Stop();
    } catch (const std::exception& e) {
        std::cerr << "Failed: " << e.what() << std::endl;
    }

    return 0;
}

Multicast Receiver

To receive multicast datagrams, bind to the multicast port and join the group using JoinMulticastGroup.

#include "cppudpnet.hpp"
#include <iostream>
#include <string>

int main() {
    // Bind to the port we expect multicast traffic on
    cppudpnet::UdpListener receiver(9000, "0.0.0.0");

    receiver.SetDataHandler([](uint64_t session_id, const cppudpnet::PeerAddress& peer,
                               const std::vector<uint8_t>& data) {
        std::string text(data.begin(), data.end());
        std::cout << "Multicast received from " << peer.ToString() << ": " << text << std::endl;
    });

    try {
        receiver.Start();
        
        // Join the multicast group
        receiver.JoinMulticastGroup("239.255.0.1");
        std::cout << "Joined multicast group 239.255.0.1. Waiting for data..." << std::endl;
        
        std::cin.get();
        receiver.Stop();
    } catch (const std::exception& e) {
        std::cerr << "Failed: " << e.what() << std::endl;
    }

    return 0;
}

Advanced Socket Options

cpp-udpnet exposes additional socket tuning options for performance and path optimization:

Don’t Fragment (DF) & PMTUD

By default, large UDP datagrams are fragmented by the IP layer. To enforce Path MTU Discovery or prevent IP-level fragmentation, enable Don’t Fragment:

// Set on UdpListener or UdpSender before Start()
client.SetDontFragment(true);

On Windows, this configures IP_DONTFRAGMENT / IPV6_DONTFRAG. On Linux, this configures IP_MTU_DISCOVER / IPV6_MTU_DISCOVER (sets IP_PMTUDISC_DO / IPV6_PMTUDISC_DO).

Max Pacing Rate

On supported Linux systems, you can enforce kernel-level packet pacing to reduce buffer overflows and packet drops at the network driver interface:

// Set pacing rate in bytes per second (e.g., 100 MB/s)
client.SetMaxPacingRate(100 * 1024 * 1024);

This configures the SO_MAX_PACING_RATE socket option. It is a no-op on non-supported platforms.

Socket Profiles (UdpProfile)

UdpSender supports the ApplyProfile() and GetProfile() methods, allowing client applications to configure receive/send socket buffers and datagram size limits in one call:

// Apply pre-configured profile
client.ApplyProfile(cppudpnet::UdpProfile::ReliableLAN());

// Query current settings
cppudpnet::UdpProfile prof = client.GetProfile();

< Previous: Advanced Usage 🏠 Home Next: Performance Metrics >