Add BulkSendApplication
authorJosh Pelkey <jpelkey@gatech.edu>
Thu, 16 Dec 2010 20:24:14 -0500
changeset 6690 3fab9a03dacd
parent 6689 e2de571e920a
child 6691 5b238a88cb60
Add BulkSendApplication
CHANGES.html
RELEASE_NOTES
examples/tcp/tcp-bulk-send.cc
examples/tcp/wscript
src/applications/bulk-send/bulk-send-application.cc
src/applications/bulk-send/bulk-send-application.h
src/applications/bulk-send/wscript
src/helper/bulk-send-helper.cc
src/helper/bulk-send-helper.h
src/helper/wscript
src/wscript
--- a/CHANGES.html	Thu Dec 16 20:17:50 2010 -0500
+++ b/CHANGES.html	Thu Dec 16 20:24:14 2010 -0500
@@ -87,6 +87,14 @@
   and packet-socket return SOCK_RAW. tcp-socket and nsc-tcp-socket return
   SOCK_STREAM. udp-socket returns SOCK_DGRAM.</p></li>
 
+<li><b>BulkSendApplication</b>
+<p>Sends data as fast as possible up to MaxBytes or unlimited if MaxBytes is 
+zero.  Think OnOff, but without the "off" and without the variable data rate. 
+This application only works with SOCK_STREAM and SOCK_SEQPACKET sockets, 
+for example TCP sockets and not UDP sockets. A helper class exists to 
+facilitate creating BulkSendApplications. The API for the helper class 
+is similar to existing application helper classes, for example, OnOff.
+
 </ul>
 
 <h2>Changes to existing API:</h2>
--- a/RELEASE_NOTES	Thu Dec 16 20:17:50 2010 -0500
+++ b/RELEASE_NOTES	Thu Dec 16 20:24:14 2010 -0500
@@ -65,6 +65,12 @@
      regression tests but they are now called from the test.py
      program.
 
+   - New BulkSendApplication sends data as fast as possible up to 
+     MaxBytes or unlimited if MaxBytes is zero.  Think OnOff, but 
+     without the "off" and without the variable data rate. This 
+     application only works with SOCK_STREAM and SOCK_SEQPACKET 
+     sockets, for example TCP sockets and not UDP sockets.
+
 Bugs fixed
 ----------
 The following lists many of the bugs fixed or small feature additions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/tcp/tcp-bulk-send.cc	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Network topology
+//
+//       n0 ----------- n1
+//            500 Kbps
+//             5 ms
+//
+// - Flow from n0 to n1 using BulkSendApplication.
+// - Tracing of queues and packet receptions to file "tcp-bulk-send.tr"
+//   and pcap tracing available when tracing is turned on.
+
+#include <string>
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+#include "ns3/node-module.h"
+#include "ns3/packet-sink.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("TcpBulkSendExample");
+
+int
+main (int argc, char *argv[])
+{
+
+  bool tracing = false;
+  uint32_t maxBytes = 0;
+
+//
+// Allow the user to override any of the defaults at
+// run-time, via command-line arguments
+//
+  CommandLine cmd;
+  cmd.AddValue ("tracing", "Flag to enable/disable tracing", tracing);
+  cmd.AddValue ("maxBytes",
+                "Total number of bytes for application to send", maxBytes);
+  cmd.Parse (argc, argv);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer nodes;
+  nodes.Create (2);
+
+  NS_LOG_INFO ("Create channels.");
+
+//
+// Explicitly create the point-to-point link required by the topology (shown above).
+//
+  PointToPointHelper pointToPoint;
+  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("500Kbps"));
+  pointToPoint.SetChannelAttribute ("Delay", StringValue ("5ms"));
+
+  NetDeviceContainer devices;
+  devices = pointToPoint.Install (nodes);
+
+//
+// Install the internet stack on the nodes
+//
+  InternetStackHelper internet;
+  internet.Install (nodes);
+
+//
+// We've got the "hardware" in place.  Now we need to add IP addresses.
+//
+  NS_LOG_INFO ("Assign IP Addresses.");
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (devices);
+
+  NS_LOG_INFO ("Create Applications.");
+
+//
+// Create a BulkSendApplication and install it on node 0
+//
+  uint16_t port = 9;  // well-known echo port number
+
+
+  BulkSendHelper source ("ns3::TcpSocketFactory",
+                         InetSocketAddress (i.GetAddress (1), port));
+  // Set the amount of data to send in bytes.  Zero is unlimited.
+  source.SetAttribute ("MaxBytes", UintegerValue (maxBytes));
+  ApplicationContainer sourceApps = source.Install (nodes.Get (0));
+  sourceApps.Start (Seconds (0.0));
+  sourceApps.Stop (Seconds (10.0));
+
+//
+// Create a PacketSinkApplication and install it on node 1
+//
+  PacketSinkHelper sink ("ns3::TcpSocketFactory",
+                         InetSocketAddress (Ipv4Address::GetAny (), port));
+  ApplicationContainer sinkApps = sink.Install (nodes.Get (1));
+  sinkApps.Start (Seconds (0.0));
+  sinkApps.Stop (Seconds (10.0));
+
+//
+// Set up tracing if enabled
+//
+  if (tracing)
+    {
+      AsciiTraceHelper ascii;
+      pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("tcp-bulk-send.tr"));
+      pointToPoint.EnablePcapAll ("tcp-bulk-send", false);
+    }
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Stop (Seconds (10.0));
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+
+  Ptr<PacketSink> sink1 = DynamicCast<PacketSink> (sinkApps.Get (0));
+  std::cout << "Total Bytes Received: " << sink1->GetTotalRx () << std::endl;
+}
--- a/examples/tcp/wscript	Thu Dec 16 20:17:50 2010 -0500
+++ b/examples/tcp/wscript	Thu Dec 16 20:24:14 2010 -0500
@@ -20,3 +20,7 @@
     obj = bld.create_ns3_program('star',
                                  ['point-to-point', 'internet-stack'])
     obj.source = 'star.cc'
+
+    obj = bld.create_ns3_program('tcp-bulk-send',
+                                 ['point-to-point', 'internet-stack'])
+    obj.source = 'tcp-bulk-send.cc'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/bulk-send/bulk-send-application.cc	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,224 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: George F. Riley <riley@ece.gatech.edu>
+ */
+
+#include "ns3/log.h"
+#include "ns3/address.h"
+#include "ns3/node.h"
+#include "ns3/nstime.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
+#include "ns3/tcp-socket-factory.h"
+#include "bulk-send-application.h"
+
+NS_LOG_COMPONENT_DEFINE ("BulkSendApplication");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (BulkSendApplication);
+
+TypeId
+BulkSendApplication::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::BulkSendApplication")
+    .SetParent<Application> ()
+    .AddConstructor<BulkSendApplication> ()
+    .AddAttribute ("SendSize", "The amount of data to send each time.",
+                   UintegerValue (512),
+                   MakeUintegerAccessor (&BulkSendApplication::m_sendSize),
+                   MakeUintegerChecker<uint32_t> (1))
+    .AddAttribute ("Remote", "The address of the destination",
+                   AddressValue (),
+                   MakeAddressAccessor (&BulkSendApplication::m_peer),
+                   MakeAddressChecker ())
+    .AddAttribute ("MaxBytes",
+                   "The total number of bytes to send. "
+                   "Once these bytes are sent, "
+                   "no data  is sent again. The value zero means "
+                   "that there is no limit.",
+                   UintegerValue (0),
+                   MakeUintegerAccessor (&BulkSendApplication::m_maxBytes),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Protocol", "The type of protocol to use.",
+                   TypeIdValue (TcpSocketFactory::GetTypeId ()),
+                   MakeTypeIdAccessor (&BulkSendApplication::m_tid),
+                   MakeTypeIdChecker ())
+    .AddTraceSource ("Tx", "A new packet is created and is sent",
+                     MakeTraceSourceAccessor (&BulkSendApplication::m_txTrace))
+  ;
+  return tid;
+}
+
+
+BulkSendApplication::BulkSendApplication ()
+  : m_socket (0),
+    m_connected (false),
+    m_totBytes (0)
+{
+  NS_LOG_FUNCTION (this);
+}
+
+BulkSendApplication::~BulkSendApplication ()
+{
+  NS_LOG_FUNCTION (this);
+}
+
+void
+BulkSendApplication::SetMaxBytes (uint32_t maxBytes)
+{
+  NS_LOG_FUNCTION (this << maxBytes);
+  m_maxBytes = maxBytes;
+}
+
+Ptr<Socket>
+BulkSendApplication::GetSocket (void) const
+{
+  NS_LOG_FUNCTION (this);
+  return m_socket;
+}
+
+void
+BulkSendApplication::DoDispose (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  m_socket = 0;
+  // chain up
+  Application::DoDispose ();
+}
+
+// Application Methods
+void BulkSendApplication::StartApplication (void) // Called at time specified by Start
+{
+  NS_LOG_FUNCTION (this);
+
+  // Create the socket if not already
+  if (!m_socket)
+    {
+      m_socket = Socket::CreateSocket (GetNode (), m_tid);
+
+      // Fatal error if socket type is not SOCK_STREAM or SOCK_SEQPACKET
+      if (m_socket->GetSocketType () != Socket::SOCK_STREAM &&
+          m_socket->GetSocketType () != Socket::SOCK_SEQPACKET)
+        {
+          NS_FATAL_ERROR ("Using BulkSend with an incompatible socket type. "
+                          "BulkSend requires SOCK_STREAM or SOCK_SEQPACKET. "
+                          "In other words, use TCP instead of UDP.");
+        }
+
+      m_socket->Bind ();
+      m_socket->Connect (m_peer);
+      m_socket->ShutdownRecv ();
+      m_socket->SetConnectCallback (
+        MakeCallback (&BulkSendApplication::ConnectionSucceeded, this),
+        MakeCallback (&BulkSendApplication::ConnectionFailed, this));
+      m_socket->SetSendCallback (
+        MakeCallback (&BulkSendApplication::DataSend, this));
+    }
+  if (m_connected)
+    {
+      SendData ();
+    }
+}
+
+void BulkSendApplication::StopApplication (void) // Called at time specified by Stop
+{
+  NS_LOG_FUNCTION (this);
+
+  if (m_socket != 0)
+    {
+      m_socket->Close ();
+      m_connected = false;
+    }
+  else
+    {
+      NS_LOG_WARN ("BulkSendApplication found null socket to close in StopApplication");
+    }
+}
+
+
+// Private helpers
+
+void BulkSendApplication::SendData (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  while (m_maxBytes == 0 || m_totBytes < m_maxBytes)
+    { // Time to send more
+      uint32_t toSend = m_sendSize;
+      // Make sure we don't send too many
+      if (m_maxBytes > 0)
+        {
+          toSend = std::min (m_sendSize, m_maxBytes - m_totBytes);
+        }
+      NS_LOG_LOGIC ("sending packet at " << Simulator::Now ());
+      Ptr<Packet> packet = Create<Packet> (toSend);
+      m_txTrace (packet);
+      int actual = m_socket->Send (packet);
+      if (actual > 0)
+        {
+          m_totBytes += actual;
+        }
+      // We exit this loop when actual < toSend as the send side
+      // buffer is full. The "DataSent" callback will pop when
+      // some buffer space has freed ip.
+      if ((unsigned)actual != toSend)
+        {
+          break;
+        }
+    }
+  // Check if time to close (all sent)
+  if (m_totBytes == m_maxBytes && m_connected)
+    {
+      m_socket->Close ();
+      m_connected = false;
+    }
+}
+
+void BulkSendApplication::ConnectionSucceeded (Ptr<Socket> socket)
+{
+  NS_LOG_FUNCTION (this << socket);
+  NS_LOG_LOGIC ("BulkSendApplication Connection succeeded");
+  m_connected = true;
+  SendData ();
+}
+
+void BulkSendApplication::ConnectionFailed (Ptr<Socket> socket)
+{
+  NS_LOG_FUNCTION (this << socket);
+  NS_LOG_LOGIC ("BulkSendApplication, Connection Failed");
+}
+
+void BulkSendApplication::DataSend (Ptr<Socket>, uint32_t)
+{
+  NS_LOG_FUNCTION (this);
+
+  if (m_connected)
+    { // Only send new data if the connection has completed
+      Simulator::ScheduleNow (&BulkSendApplication::SendData, this);
+    }
+}
+
+
+
+} // Namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/bulk-send/bulk-send-application.h	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,107 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2010 Georgia Institute of Technology
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: George F. Riley <riley@ece.gatech.edu>
+ */
+
+#ifndef __bulksend_application_h__
+#define __bulksend_application_h__
+
+#include "ns3/address.h"
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/traced-callback.h"
+
+namespace ns3 {
+
+class Address;
+class RandomVariable;
+class Socket;
+
+/**
+ * \ingroup applications
+ * \defgroup bulksend BulkSendApplication
+ *
+ * This traffic generator simply sends data
+ * as fast as possible up to MaxBytes or until
+ * the appplication is stopped if MaxBytes is
+ * zero. Once the lower layer send buffer is
+ * filled, it waits until space is free to
+ * send more data, essentially keeping a
+ * constant flow of data. Only SOCK_STREAM 
+ * and SOCK_SEQPACKET sockets are supported. 
+ * For example, TCP sockets can be used, but 
+ * UDP sockets can not be used.
+ */
+class BulkSendApplication : public Application
+{
+public:
+  static TypeId GetTypeId (void);
+
+  BulkSendApplication ();
+
+  virtual ~BulkSendApplication ();
+
+  /**
+   * \param maxBytes the upper bound of bytes to send
+   *
+   * Set the upper bound for the total number of bytes to send. Once 
+   * this bound is reached, no more application bytes are sent. If the 
+   * application is stopped during the simulation and restarted, the 
+   * total number of bytes sent is not reset; however, the maxBytes 
+   * bound is still effective and the application will continue sending 
+   * up to maxBytes. The value zero for maxBytes means that 
+   * there is no upper bound; i.e. data is sent until the application 
+   * or simulation is stopped.
+   */
+  void SetMaxBytes (uint32_t maxBytes);
+
+  /**
+   * \return pointer to associated socket
+   */
+  Ptr<Socket> GetSocket (void) const;
+
+protected:
+  virtual void DoDispose (void);
+private:
+  // inherited from Application base class.
+  virtual void StartApplication (void);    // Called at time specified by Start
+  virtual void StopApplication (void);     // Called at time specified by Stop
+
+  void SendData ();
+
+  Ptr<Socket>     m_socket;       // Associated socket
+  Address         m_peer;         // Peer address
+  bool            m_connected;    // True if connected
+  uint32_t        m_sendSize;     // Size of data to send each time
+  uint32_t        m_maxBytes;     // Limit total number of bytes sent
+  uint32_t        m_totBytes;     // Total bytes sent so far
+  TypeId          m_tid;
+  TracedCallback<Ptr<const Packet> > m_txTrace;
+
+private:
+  void ConnectionSucceeded (Ptr<Socket> socket);
+  void ConnectionFailed (Ptr<Socket> socket);
+  void DataSend (Ptr<Socket>, uint32_t); // for socket's SetSendCallback
+  void Ignore (Ptr<Socket> socket);
+};
+
+} // namespace ns3
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/bulk-send/wscript	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,13 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    module = bld.create_ns3_module('bulk-send', ['core', 'simulator', 'node'])
+    module.source = [
+        'bulk-send-application.cc',
+        ]
+    headers = bld.new_task_gen('ns3header')
+    headers.module = 'bulk-send'
+    headers.source = [
+        'bulk-send-application.h',
+        ]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/bulk-send-helper.cc	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Geoge Riley <riley@ece.gatech.edu>
+ * Adapted from OnOffHelper by:
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "bulk-send-helper.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/packet-socket-address.h"
+#include "ns3/string.h"
+#include "ns3/names.h"
+
+namespace ns3 {
+
+BulkSendHelper::BulkSendHelper (std::string protocol, Address address)
+{
+  m_factory.SetTypeId ("ns3::BulkSendApplication");
+  m_factory.Set ("Protocol", StringValue (protocol));
+  m_factory.Set ("Remote", AddressValue (address));
+}
+
+void
+BulkSendHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+  m_factory.Set (name, value);
+}
+
+ApplicationContainer
+BulkSendHelper::Install (Ptr<Node> node) const
+{
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+BulkSendHelper::Install (std::string nodeName) const
+{
+  Ptr<Node> node = Names::Find<Node> (nodeName);
+  return ApplicationContainer (InstallPriv (node));
+}
+
+ApplicationContainer
+BulkSendHelper::Install (NodeContainer c) const
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      apps.Add (InstallPriv (*i));
+    }
+
+  return apps;
+}
+
+Ptr<Application>
+BulkSendHelper::InstallPriv (Ptr<Node> node) const
+{
+  Ptr<Application> app = m_factory.Create<Application> ();
+  node->AddApplication (app);
+
+  return app;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/bulk-send-helper.h	Thu Dec 16 20:24:14 2010 -0500
@@ -0,0 +1,111 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * 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 General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Geoge Riley <riley@ece.gatech.edu>
+ * Adapted from OnOffHelper by:
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef BULK_SEND_HELPER_H
+#define BULK_SEND_HELPER_H
+
+#include <stdint.h>
+#include <string>
+#include "ns3/object-factory.h"
+#include "ns3/address.h"
+#include "ns3/attribute.h"
+#include "ns3/net-device.h"
+#include "node-container.h"
+#include "application-container.h"
+
+namespace ns3 {
+
+/**
+ * \brief A helper to make it easier to instantiate an ns3::BulkSendApplication
+ * on a set of nodes.
+ */
+class BulkSendHelper
+{
+public:
+  /**
+   * Create an BulkSendHelper to make it easier to work with BulkSendApplications
+   *
+   * \param protocol the name of the protocol to use to send traffic
+   *        by the applications. This string identifies the socket
+   *        factory type used to create sockets for the applications.
+   *        A typical value would be ns3::UdpSocketFactory.
+   * \param address the address of the remote node to send traffic
+   *        to.
+   */
+  BulkSendHelper (std::string protocol, Address address);
+
+  /**
+   * Helper function used to set the underlying application attributes, 
+   * _not_ the socket attributes.
+   *
+   * \param name the name of the application attribute to set
+   * \param value the value of the application attribute to set
+   */
+  void SetAttribute (std::string name, const AttributeValue &value);
+
+  /**
+   * Install an ns3::BulkSendApplication on each node of the input container
+   * configured with all the attributes set with SetAttribute.
+   *
+   * \param c NodeContainer of the set of nodes on which an BulkSendApplication
+   * will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (NodeContainer c) const;
+
+  /**
+   * Install an ns3::BulkSendApplication on the node configured with all the
+   * attributes set with SetAttribute.
+   *
+   * \param node The node on which an BulkSendApplication will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (Ptr<Node> node) const;
+
+  /**
+   * Install an ns3::BulkSendApplication on the node configured with all the
+   * attributes set with SetAttribute.
+   *
+   * \param nodeName The node on which an BulkSendApplication will be installed.
+   * \returns Container of Ptr to the applications installed.
+   */
+  ApplicationContainer Install (std::string nodeName) const;
+
+private:
+  /**
+   * \internal
+   * Install an ns3::BulkSendApplication on the node configured with all the
+   * attributes set with SetAttribute.
+   *
+   * \param node The node on which an BulkSendApplication will be installed.
+   * \returns Ptr to the application installed.
+   */
+  Ptr<Application> InstallPriv (Ptr<Node> node) const;
+  std::string m_protocol;
+  Address m_remote;
+  ObjectFactory m_factory;
+};
+
+} // namespace ns3
+
+#endif /* ON_OFF_HELPER_H */
+
--- a/src/helper/wscript	Thu Dec 16 20:17:50 2010 -0500
+++ b/src/helper/wscript	Thu Dec 16 20:24:14 2010 -0500
@@ -47,6 +47,7 @@
         'topology-reader-helper.cc',
         'waveform-generator-helper.cc',
         'spectrum-analyzer-helper.cc',
+        'bulk-send-helper.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -97,6 +98,7 @@
         'topology-reader-helper.h',
         'waveform-generator-helper.h',
         'spectrum-analyzer-helper.h',
+        'bulk-send-helper.h',
         ]
 
     env = bld.env_of_name('default')
--- a/src/wscript	Thu Dec 16 20:17:50 2010 -0500
+++ b/src/wscript	Thu Dec 16 20:24:14 2010 -0500
@@ -33,6 +33,7 @@
     'applications/onoff',
     'applications/packet-sink',
     'applications/udp-echo',
+    'applications/bulk-send',
     'routing/nix-vector-routing',
     'routing/olsr',
     'routing/global-routing',