<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.nsnam.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=HOWTO_create_a_traffic_generator</id>
	<title>HOWTO create a traffic generator - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.nsnam.org/mediawiki/index.php?action=history&amp;feed=atom&amp;title=HOWTO_create_a_traffic_generator"/>
	<link rel="alternate" type="text/html" href="https://www.nsnam.org/mediawiki/index.php?title=HOWTO_create_a_traffic_generator&amp;action=history"/>
	<updated>2026-05-05T13:20:01Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://www.nsnam.org/mediawiki/index.php?title=HOWTO_create_a_traffic_generator&amp;diff=2779&amp;oldid=prev</id>
		<title>Jpelkey: New page: {{TOC}}  It is often desirable to create a new traffic generator for your simulation purposes.  Since it is possible to instantiate Packet objects, schedule events, and call functions from...</title>
		<link rel="alternate" type="text/html" href="https://www.nsnam.org/mediawiki/index.php?title=HOWTO_create_a_traffic_generator&amp;diff=2779&amp;oldid=prev"/>
		<updated>2009-05-22T13:59:19Z</updated>

		<summary type="html">&lt;p&gt;New page: {{TOC}}  It is often desirable to create a new traffic generator for your simulation purposes.  Since it is possible to instantiate Packet objects, schedule events, and call functions from...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{TOC}}&lt;br /&gt;
&lt;br /&gt;
It is often desirable to create a new traffic generator for your simulation purposes.  Since it is possible to instantiate Packet objects, schedule events, and call functions from any piece of code in ns-3, technically, there is no single answer to the question of how we can write a new traffic generator. However, the Socket API was really designed to be the single point of entry for traffic generators or traffic analyzers and the Application class was designed to hold together any number of sockets.&lt;br /&gt;
&lt;br /&gt;
== HOWTO create a traffic generator ==&lt;br /&gt;
&lt;br /&gt;
Implementing a new traffic generator thus boils down to:&lt;br /&gt;
&lt;br /&gt;
    * implementing a new subclass of the Application base class&lt;br /&gt;
    * instantiate one or many sockets within that application&lt;br /&gt;
    * start scheduling events when StartApplication is called&lt;br /&gt;
    * stop scheduling events when StopApplication is called&lt;br /&gt;
    * create packets and send them over one or many sockets in each event&lt;br /&gt;
&lt;br /&gt;
The following &amp;quot;random&amp;quot; generator generates packets separated by a random delay and with a random size.&lt;br /&gt;
&lt;br /&gt;
    class RandomGenerator : public Application&lt;br /&gt;
    {&lt;br /&gt;
    public:&lt;br /&gt;
      RandomGenerator ();&lt;br /&gt;
      void SetDelay (RandomVariable delay);&lt;br /&gt;
      void SetSize (RandomVariable size);&lt;br /&gt;
      void SetRemote (std::string socketType, &lt;br /&gt;
                      Address remote);&lt;br /&gt;
    private:&lt;br /&gt;
      virtual void StartApplication (void);&lt;br /&gt;
      virtual void StopApplication (void);&lt;br /&gt;
      void DoGenerate (void);&lt;br /&gt;
      RandomVariable m_delay;&lt;br /&gt;
      RandomVariable m_size;&lt;br /&gt;
      Ptr&amp;lt;Socket&amp;gt; m_socket;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
The socket is created in the SetRemote method: &lt;br /&gt;
&lt;br /&gt;
    void &lt;br /&gt;
    RandomGenerator::SetRemote (std::string socketType, &lt;br /&gt;
                                Address remote)&lt;br /&gt;
    {&lt;br /&gt;
      TypeId tid = TypeId::LookupByName (socketType);&lt;br /&gt;
      m_socket = Socket::CreateSocket (GetNode (), tid);&lt;br /&gt;
      m_socket-&amp;gt;Bind ();&lt;br /&gt;
      m_socket-&amp;gt;ShutdownRecv ();&lt;br /&gt;
      m_socket-&amp;gt;Connect (remote);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
While the the crux of the logic is located in the DoGenerate method which is called from within StartApplication: &lt;br /&gt;
&lt;br /&gt;
    void&lt;br /&gt;
    RandomGenerator::DoGenerate (void)&lt;br /&gt;
    {&lt;br /&gt;
      m_next = Simulator::Schedule (Seconds (m_delay.GetValue ()), &lt;br /&gt;
                    &amp;amp;RandomGenerator::DoGenerate, this);&lt;br /&gt;
      Ptr&amp;lt;Packet&amp;gt; p = Create&amp;lt;Packet&amp;gt; (m_size.GetIntValue ());&lt;br /&gt;
      m_socket-&amp;gt;Send (p);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
To make that application more integrated in ns-3, it needs an associated helper class: &lt;br /&gt;
&lt;br /&gt;
    class RandomAppHelper&lt;br /&gt;
    {&lt;br /&gt;
    public:&lt;br /&gt;
      RandomAppHelper (std::string protocol, Address remote);&lt;br /&gt;
      void SetPacketSize (RandomVariable packetSize);&lt;br /&gt;
      void SetDelay (RandomVariable delay);&lt;br /&gt;
      ApplicationContainer Install (NodeContainer nodes);&lt;br /&gt;
    private:&lt;br /&gt;
      std::string m_protocol;&lt;br /&gt;
      Address m_remote;&lt;br /&gt;
      RandomVariable m_packetSize;&lt;br /&gt;
      RandomVariable m_delay;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
which could be trivially implemented as: &lt;br /&gt;
&lt;br /&gt;
    ApplicationContainer &lt;br /&gt;
    RandomAppHelper::Install (NodeContainer nodes)&lt;br /&gt;
    {&lt;br /&gt;
      ApplicationContainer applications;&lt;br /&gt;
      for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)&lt;br /&gt;
        {&lt;br /&gt;
          Ptr&amp;lt;RandomAppHelper&amp;gt; app = CreateObject&amp;lt;RandomAppHelper&amp;gt; ();&lt;br /&gt;
          app-&amp;gt;SetSize (m_packetSize);&lt;br /&gt;
          app-&amp;gt;SetDelay (m_delay);&lt;br /&gt;
          app-&amp;gt;SetRemote (m_protocol, m_remote);&lt;br /&gt;
          (*i)-&amp;gt;AddApplication (app);&lt;br /&gt;
          applications.Add (app);&lt;br /&gt;
        }&lt;br /&gt;
      return applications;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
Despite being functional, this API is not very consistant with the style of the other helper classes, all of which allow you to control the parameters of the underlying class through attributes and not explicit setters. The following API thus replaces the pair SetPacketSize/SetDelay with a single method SetAttribute:&lt;br /&gt;
&lt;br /&gt;
    class RandomAppHelper&lt;br /&gt;
    {&lt;br /&gt;
    public:&lt;br /&gt;
      RandomAppHelper (std::string protocol, Address remote);&lt;br /&gt;
      void SetAttribute (std::string name, const AttributeValue &amp;amp;value);&lt;br /&gt;
      ApplicationContainer Install (NodeContainer c);&lt;br /&gt;
    private:&lt;br /&gt;
      std::string m_protocol;&lt;br /&gt;
      Address m_remote;&lt;br /&gt;
      ObjectFactory m_factory;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
And which can be used as follows: &lt;br /&gt;
&lt;br /&gt;
    RandomAppHelper app = RandomAppHelper (&amp;quot;ns3::TcpSocketFactory&amp;quot;, &lt;br /&gt;
                           InetSocketAddress (Ipv4Address (&amp;quot;192.168.1.10&amp;quot;), 10));&lt;br /&gt;
    app.SetAttribute (&amp;quot;Delay&amp;quot;, StringValue (&amp;quot;Constant:2.5&amp;quot;));&lt;br /&gt;
    app.SetAttribute (&amp;quot;Size&amp;quot;, StringValue (&amp;quot;Constant:2100&amp;quot;));&lt;br /&gt;
    app.Install (nodes);&lt;br /&gt;
&lt;br /&gt;
The implementation, in this case, is not necessarily longer but its simplicity hides a lot of behind-the-scenes complexity:&lt;br /&gt;
&lt;br /&gt;
    void &lt;br /&gt;
    RandomAppHelper::SetAttribute (std::string name, const AttributeValue &amp;amp;value)&lt;br /&gt;
    {&lt;br /&gt;
      m_factory.Set (name, value);&lt;br /&gt;
    }&lt;br /&gt;
    ApplicationContainer &lt;br /&gt;
    RandomAppHelper::Install (NodeContainer nodes)&lt;br /&gt;
    {&lt;br /&gt;
      ApplicationContainer applications;&lt;br /&gt;
      for (NodeContainer::Iterator i = nodes.Begin (); i != nodes.End (); ++i)&lt;br /&gt;
        {&lt;br /&gt;
          Ptr&amp;lt;RandomAppHelper&amp;gt; app = m_factory.Create&amp;lt;RandomAppHelper&amp;gt; ();&lt;br /&gt;
          app-&amp;gt;SetRemote (m_socketType, m_remote);&lt;br /&gt;
          (*i)-&amp;gt;AddApplication (app);&lt;br /&gt;
          applications.Add (app);&lt;br /&gt;
        }&lt;br /&gt;
      return applications;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
The key difference between this implementation and the previous one is that this helper does not handle explicitely the attributes delay and packet size. Instead, it stores them in an ObjectFactory object. This, of course, does not work magically, and requires extra support from the underlying RandomGenerator class. Specifically, it requires that the underlying RandomGenerator defines its attributes in its TypeId in a new public static method:&lt;br /&gt;
&lt;br /&gt;
    class RandomGenerator&lt;br /&gt;
    {&lt;br /&gt;
    public:&lt;br /&gt;
      static TypeId GetTypeId (void);&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
The corresponding implementation is shown below:&lt;br /&gt;
&lt;br /&gt;
    TypeId&lt;br /&gt;
    RandomGenerator::GetTypeId (void)&lt;br /&gt;
    {&lt;br /&gt;
      static TypeId tid = TypeId (&amp;quot;RandomGenerator&amp;quot;)&lt;br /&gt;
        .SetParent&amp;lt;Application&amp;gt; ()&lt;br /&gt;
        .AddConstructor&amp;lt;RandomGenerator&amp;gt; ()&lt;br /&gt;
        .AddAttribute (&amp;quot;Delay&amp;quot;, &amp;quot;The delay between two packets (s)&amp;quot;,&lt;br /&gt;
               RandomVariableValue (ConstantVariable (1.0)),&lt;br /&gt;
               MakeRandomVariableAccessor (&amp;amp;RandomGenerator::m_delay),&lt;br /&gt;
               MakeRandomVariableChecker ())&lt;br /&gt;
        .AddAttribute (&amp;quot;PacketSize&amp;quot;, &amp;quot;The size of each packet (bytes)&amp;quot;,&lt;br /&gt;
               RandomVariableValue (ConstantVariable (2000)),&lt;br /&gt;
               MakeRandomVariableAccessor (&amp;amp;RandomGenerator::m_size),&lt;br /&gt;
               MakeRandomVariableChecker ())&lt;br /&gt;
        ;&lt;br /&gt;
      return tid;&lt;br /&gt;
    }&lt;/div&gt;</summary>
		<author><name>Jpelkey</name></author>
	</entry>
</feed>