IPv4 UDPPoset Endpoint: Partially Ordered UDP communication points

This class provides the concept of aggregating a single data transmission to multiple UDP addresses.

Although multicasting is a better solution, sometimes multicasting is not possible with certain architectures; hence UDPPoset.

The advantage of UDPPoset over a vector of UDP sockets is that each instantiation of a UDP socket will use a local port. In contrast, the UDPPoset class will use a single port for all outgoing UDP traffic. Like the UDP class it inherits from, it is capable of receiving transmissions, but only for the single local port.

UDPPoset will only accept UDP unicast addresses; not multicast; not broadcast.

The name poset, or partially ordered set, was used since UDP destinations of equal priority have no guarantees on ordering. Priority is a numeric value, and transmissions will occur from the highest priority first to the lowest priority last.

IPv4 UDP poset client example

This client sends to three destinations.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <glibmm.h>

#include <iostream>

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

  // The data to send
  Glib::ustring data;
  Glib::ustring host;
  int port1, port2, port3;

  Glib::OptionContext option_context( "- IPv4 UDP POset Client" );
  Glib::OptionGroup option_group( "Options", "" );

  Glib::OptionEntry option_data;
  option_data.set_long_name( "data" );
  option_data.set_description( "Data to send [default=\"0123456789\"]" );
  option_group.add_entry( option_data, data );

  Glib::OptionEntry option_host;
  option_host.set_long_name( "tgt" );
  option_host.set_description( "Target host to send data to [default=127.0.0.1]" );
  option_group.add_entry( option_host, host );

  Glib::OptionEntry option_port1;
  option_port1.set_long_name( "port1" );
  option_port1.set_description( "UDP port1 to send data to [default=1500]" );
  option_group.add_entry( option_port1, port1 );

  Glib::OptionEntry option_port2;
  option_port2.set_long_name( "port2" );
  option_port2.set_description( "UDP port2 to send data to [default=1501]" );
  option_group.add_entry( option_port2, port2 );

  Glib::OptionEntry option_port3;
  option_port3.set_long_name( "port3" );
  option_port3.set_description( "UDP port3 to send data to [default=1502]" );
  option_group.add_entry( option_port3, port3 );

  option_context.set_main_group( option_group );

  option_context.parse( argc, argv );

  if ( data.size() == 0 ) data = "0123456789";
  if ( host.size() == 0 ) host = "127.0.0.1";
  if ( port1 == 0 ) port1 = 1500;
  if ( port2 == 0 ) port2 = 1501;
  if ( port3 == 0 ) port3 = 1502;

  Conexus::init();

  // declare the local UDP connection point
  Conexus::IPv4::UDPPoset::pointer udpposet = Conexus::IPv4::UDPPoset::create();

  // Example of using the connect and send method. The send method doesn't
  // require an address, but instead requires a connected UDP object and
  // just sends to the connected destination.
  udpposet->add_destination(host, port1, 0);
  udpposet->add_destination(host, port2, 1);
  udpposet->add_destination(host, port3, -1);
  udpposet->write(data.c_str(), 11);

  return 0;
}

IPv4 UDP poset server example

This server receives on three ports.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <sys/types.h>
#include <unistd.h>
#include <iostream>

// prototypes of the three print callback functions
void print_data1(const Conexus::Data d);
void print_data2(const Conexus::Data d);
void print_data3(const Conexus::Data d);

int main() {
  // Initialize the Conexus library
  // This is needed because we will use threaded servers and this
  // will do all the behind the scenes work to initialize pthreads
  Conexus::init();

  // Declare the udp object
  Conexus::IPv4::UDP::pointer udp1 = Conexus::IPv4::UDP::create(1500);
  Conexus::IPv4::UDP::pointer udp2 = Conexus::IPv4::UDP::create(1501);
  Conexus::IPv4::UDP::pointer udp3 = Conexus::IPv4::UDP::create(1502);

  // The server connect method connects a provided sigc++ slot that will be called
  // back when the server receives any data.
  udp1->signal_data().connect(sigc::ptr_fun(&print_data1));
  udp2->signal_data().connect(sigc::ptr_fun(&print_data2));
  udp3->signal_data().connect(sigc::ptr_fun(&print_data3));

  // Start the server. The server will spawn a separate thread to service
  // received data, so this call will immediately return after the thread
  // is spawned.
  udp1->start();
  udp2->start();
  udp3->start();

  std::cout << "Main thread pid: " << pthread_self() << std::endl;
  // Set up a loop that will run for 20 seconds and print the time every 5
  // seconds. Since the server is threaded, the sleep(1) call will not effect
  // the servicing thread.
  std::cout << "Starting..." << std::endl;
  for (int i=1; i <= 20; i++) {
    if (i%5 == 0)
      std::cout << "Time: " << i << std::endl;
    sleep(1);
  }

  // Stop the server and prepare for shutdown
  udp1->stop();
  udp2->stop();
  udp3->stop();

  return 0;
}

// These are the three callback functions. Each simply prints out the data received.

void print_data1(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<1> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data2(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<2> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data3(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<3> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

This class provides the concept of aggregating a single data transmission to multiple UDP addresses.

Although multicasting is a better solution, sometimes multicasting is not possible with certain architectures; hence UDPPoset.

The advantage of UDPPoset over a vector of UDP sockets is that each instantiation of a UDP socket will use a local port. In contrast, the UDPPoset class will use a single port for all outgoing UDP traffic. Like the UDP class it inherits from, it is capable of receiving transmissions, but only for the single local port.

UDPPoset will only accept UDP unicast addresses; not multicast; not broadcast.

The name poset, or partially ordered set, was used since UDP destinations of equal priority have no guarantees on ordering. Priority is a numeric value, and transmissions will occur from the highest priority first to the lowest priority last.

IPv4 UDP poset client example

This client sends to three destinations.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <glibmm.h>

#include <iostream>

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

  // The data to send
  Glib::ustring data;
  Glib::ustring host;
  int port1, port2, port3;

  Glib::OptionContext option_context( "- IPv4 UDP POset Client" );
  Glib::OptionGroup option_group( "Options", "" );

  Glib::OptionEntry option_data;
  option_data.set_long_name( "data" );
  option_data.set_description( "Data to send [default=\"0123456789\"]" );
  option_group.add_entry( option_data, data );

  Glib::OptionEntry option_host;
  option_host.set_long_name( "tgt" );
  option_host.set_description( "Target host to send data to [default=127.0.0.1]" );
  option_group.add_entry( option_host, host );

  Glib::OptionEntry option_port1;
  option_port1.set_long_name( "port1" );
  option_port1.set_description( "UDP port1 to send data to [default=1500]" );
  option_group.add_entry( option_port1, port1 );

  Glib::OptionEntry option_port2;
  option_port2.set_long_name( "port2" );
  option_port2.set_description( "UDP port2 to send data to [default=1501]" );
  option_group.add_entry( option_port2, port2 );

  Glib::OptionEntry option_port3;
  option_port3.set_long_name( "port3" );
  option_port3.set_description( "UDP port3 to send data to [default=1502]" );
  option_group.add_entry( option_port3, port3 );

  option_context.set_main_group( option_group );

  option_context.parse( argc, argv );

  if ( data.size() == 0 ) data = "0123456789";
  if ( host.size() == 0 ) host = "127.0.0.1";
  if ( port1 == 0 ) port1 = 1500;
  if ( port2 == 0 ) port2 = 1501;
  if ( port3 == 0 ) port3 = 1502;

  Conexus::init();

  // declare the local UDP connection point
  Conexus::IPv4::UDPPoset::pointer udpposet = Conexus::IPv4::UDPPoset::create();

  // Example of using the connect and send method. The send method doesn't
  // require an address, but instead requires a connected UDP object and
  // just sends to the connected destination.
  udpposet->add_destination(host, port1, 0);
  udpposet->add_destination(host, port2, 1);
  udpposet->add_destination(host, port3, -1);
  udpposet->write(data.c_str(), 11);

  return 0;
}

IPv4 UDP poset server example

This server receives on three ports.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <sys/types.h>
#include <unistd.h>
#include <iostream>

// prototypes of the three print callback functions
void print_data1(const Conexus::Data d);
void print_data2(const Conexus::Data d);
void print_data3(const Conexus::Data d);

int main() {
  // Initialize the Conexus library
  // This is needed because we will use threaded servers and this
  // will do all the behind the scenes work to initialize pthreads
  Conexus::init();

  // Declare the udp object
  Conexus::IPv4::UDP::pointer udp1 = Conexus::IPv4::UDP::create(1500);
  Conexus::IPv4::UDP::pointer udp2 = Conexus::IPv4::UDP::create(1501);
  Conexus::IPv4::UDP::pointer udp3 = Conexus::IPv4::UDP::create(1502);

  // The server connect method connects a provided sigc++ slot that will be called
  // back when the server receives any data.
  udp1->signal_data().connect(sigc::ptr_fun(&print_data1));
  udp2->signal_data().connect(sigc::ptr_fun(&print_data2));
  udp3->signal_data().connect(sigc::ptr_fun(&print_data3));

  // Start the server. The server will spawn a separate thread to service
  // received data, so this call will immediately return after the thread
  // is spawned.
  udp1->start();
  udp2->start();
  udp3->start();

  std::cout << "Main thread pid: " << pthread_self() << std::endl;
  // Set up a loop that will run for 20 seconds and print the time every 5
  // seconds. Since the server is threaded, the sleep(1) call will not effect
  // the servicing thread.
  std::cout << "Starting..." << std::endl;
  for (int i=1; i <= 20; i++) {
    if (i%5 == 0)
      std::cout << "Time: " << i << std::endl;
    sleep(1);
  }

  // Stop the server and prepare for shutdown
  udp1->stop();
  udp2->stop();
  udp3->stop();

  return 0;
}

// These are the three callback functions. Each simply prints out the data received.

void print_data1(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<1> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data2(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<2> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data3(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<3> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

This class provides the concept of aggregating a single data transmission to multiple UDP addresses.

Although multicasting is a better solution, sometimes multicasting is not possible with certain architectures; hence UDPPoset.

The advantage of UDPPoset over a vector of UDP sockets is that each instantiation of a UDP socket will use a local port. In contrast, the UDPPoset class will use a single port for all outgoing UDP traffic. Like the UDP class it inherits from, it is capable of receiving transmissions, but only for the single local port.

UDPPoset will only accept UDP unicast addresses; not multicast; not broadcast.

The name poset, or partially ordered set, was used since UDP destinations of equal priority have no guarantees on ordering. Priority is a numeric value, and transmissions will occur from the highest priority first to the lowest priority last.

IPv4 UDP poset client example

This client sends to three destinations.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <glibmm.h>

#include <iostream>

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

  // The data to send
  Glib::ustring data;
  Glib::ustring host;
  int port1, port2, port3;

  Glib::OptionContext option_context( "- IPv4 UDP POset Client" );
  Glib::OptionGroup option_group( "Options", "" );

  Glib::OptionEntry option_data;
  option_data.set_long_name( "data" );
  option_data.set_description( "Data to send [default=\"0123456789\"]" );
  option_group.add_entry( option_data, data );

  Glib::OptionEntry option_host;
  option_host.set_long_name( "tgt" );
  option_host.set_description( "Target host to send data to [default=127.0.0.1]" );
  option_group.add_entry( option_host, host );

  Glib::OptionEntry option_port1;
  option_port1.set_long_name( "port1" );
  option_port1.set_description( "UDP port1 to send data to [default=1500]" );
  option_group.add_entry( option_port1, port1 );

  Glib::OptionEntry option_port2;
  option_port2.set_long_name( "port2" );
  option_port2.set_description( "UDP port2 to send data to [default=1501]" );
  option_group.add_entry( option_port2, port2 );

  Glib::OptionEntry option_port3;
  option_port3.set_long_name( "port3" );
  option_port3.set_description( "UDP port3 to send data to [default=1502]" );
  option_group.add_entry( option_port3, port3 );

  option_context.set_main_group( option_group );

  option_context.parse( argc, argv );

  if ( data.size() == 0 ) data = "0123456789";
  if ( host.size() == 0 ) host = "127.0.0.1";
  if ( port1 == 0 ) port1 = 1500;
  if ( port2 == 0 ) port2 = 1501;
  if ( port3 == 0 ) port3 = 1502;

  Conexus::init();

  // declare the local UDP connection point
  Conexus::IPv4::UDPPoset::pointer udpposet = Conexus::IPv4::UDPPoset::create();

  // Example of using the connect and send method. The send method doesn't
  // require an address, but instead requires a connected UDP object and
  // just sends to the connected destination.
  udpposet->add_destination(host, port1, 0);
  udpposet->add_destination(host, port2, 1);
  udpposet->add_destination(host, port3, -1);
  udpposet->write(data.c_str(), 11);

  return 0;
}

IPv4 UDP poset server example

This server receives on three ports.
/***************************************************************************
 *   Copyright (C) 2001 by Rick L. Vinyard, Jr.                            *
 *   rvinyard@cs.nmsu.edu                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Lesser General Public License as        *
 *   published by the Free Software Foundation version 2.1.                *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Lesser General Public      *
 *   License along with this library; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
 ***************************************************************************/
#include <conexus.h>

#include <sys/types.h>
#include <unistd.h>
#include <iostream>

// prototypes of the three print callback functions
void print_data1(const Conexus::Data d);
void print_data2(const Conexus::Data d);
void print_data3(const Conexus::Data d);

int main() {
  // Initialize the Conexus library
  // This is needed because we will use threaded servers and this
  // will do all the behind the scenes work to initialize pthreads
  Conexus::init();

  // Declare the udp object
  Conexus::IPv4::UDP::pointer udp1 = Conexus::IPv4::UDP::create(1500);
  Conexus::IPv4::UDP::pointer udp2 = Conexus::IPv4::UDP::create(1501);
  Conexus::IPv4::UDP::pointer udp3 = Conexus::IPv4::UDP::create(1502);

  // The server connect method connects a provided sigc++ slot that will be called
  // back when the server receives any data.
  udp1->signal_data().connect(sigc::ptr_fun(&print_data1));
  udp2->signal_data().connect(sigc::ptr_fun(&print_data2));
  udp3->signal_data().connect(sigc::ptr_fun(&print_data3));

  // Start the server. The server will spawn a separate thread to service
  // received data, so this call will immediately return after the thread
  // is spawned.
  udp1->start();
  udp2->start();
  udp3->start();

  std::cout << "Main thread pid: " << pthread_self() << std::endl;
  // Set up a loop that will run for 20 seconds and print the time every 5
  // seconds. Since the server is threaded, the sleep(1) call will not effect
  // the servicing thread.
  std::cout << "Starting..." << std::endl;
  for (int i=1; i <= 20; i++) {
    if (i%5 == 0)
      std::cout << "Time: " << i << std::endl;
    sleep(1);
  }

  // Stop the server and prepare for shutdown
  udp1->stop();
  udp2->stop();
  udp3->stop();

  return 0;
}

// These are the three callback functions. Each simply prints out the data received.

void print_data1(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<1> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data2(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<2> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

void print_data3(const Conexus::Data d) {
  std::cout << "Responding thread pid: " << pthread_self() << std::endl;
  std::cout << "<3> Received " << d.size() << " bytes of data [" << d.data() << "]\n";
}

Generated on Tue Mar 13 19:54:49 2007 by  doxygen 1.5.1