How to measure the queue length?

 

test-dumbbell1.cc (put this file under scratch)

#include <iostream>

 

#include "ns3/core-module.h"

#include "ns3/network-module.h"

#include "ns3/internet-module.h"

#include "ns3/point-to-point-module.h"

#include "ns3/netanim-module.h"

#include "ns3/applications-module.h"

#include "ns3/point-to-point-layout-module.h"

#include "ns3/string.h"

#include <boost/lexical_cast.hpp>

#include "ns3/flow-monitor-module.h"

#include "ns3/traffic-control-module.h"

 

using namespace ns3;

using namespace boost;

 

QueueDiscContainer queueDiscs;

 

void PrintCurrentQueueSize() {

  Time now = Simulator::Now ();       

  std::cout << now.GetSeconds()  << "\t" << queueDiscs.Get(0)->GetNPackets() << std::endl;

  Simulator::Schedule (MilliSeconds (1), &PrintCurrentQueueSize);

}

 

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

{

  uint32_t    nLeaf = 2; 

  uint32_t    rngSeed = 1;

  std::string queueDiscType = "fifo";

 

  // Queue parameters

  uint32_t queueDiscLimitPackets = 100;

  double minTh = 15;     // RED parameters

  double maxTh = 60;    // RED parameters

  double dropprob = 0.0;

 

  CommandLine cmd (__FILE__);

  cmd.AddValue ("nLeaf", "Number of leaf nodes for each side", nLeaf);

  cmd.AddValue ("rngSeed", "random number generator seed", rngSeed);

  cmd.AddValue ("queueDiscType", "Set Queue Discipline Type", queueDiscType);

  cmd.AddValue ("DropProb", "Random Drop Probability", dropprob);

 

  cmd.Parse (argc,argv);

  RngSeedManager::SetSeed (rngSeed);

  RngSeedManager::SetRun (1);

 

  NodeContainer router_0;

  router_0.Create (1);

  NodeContainer router_1;

  router_1.Create (1);

  NodeContainer LeafNodes;

  LeafNodes.Create (nLeaf*2);  // left side and right side 

 

  TrafficControlHelper tch;

  if (queueDiscType == "red") {

    tch.SetRootQueueDisc ("ns3::RedQueueDisc");

    Config::SetDefault ("ns3::RedQueueDisc::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, queueDiscLimitPackets)));

    Config::SetDefault ("ns3::RedQueueDisc::MinTh", DoubleValue (minTh));

    Config::SetDefault ("ns3::RedQueueDisc::MaxTh", DoubleValue (maxTh));

  } else if (queueDiscType == "fifo") {

    tch.SetRootQueueDisc ("ns3::FifoQueueDisc");

    Config::SetDefault ("ns3::FifoQueueDisc::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, queueDiscLimitPackets)));

  } else if (queueDiscType == "randomdrop") {

    tch.SetRootQueueDisc ("ns3::RandomdropQueueDisc");

    Config::SetDefault ("ns3::RandomdropQueueDisc::MaxSize", QueueSizeValue (QueueSize (QueueSizeUnit::PACKETS, queueDiscLimitPackets)));

    Config::SetDefault ("ns3::RandomdropQueueDisc::DropProb", DoubleValue (dropprob));

  }

 

  /* Install the IP stack. */

  InternetStackHelper internetStackH;

  internetStackH.Install (router_0);

  internetStackH.Install (router_1);

  internetStackH.Install (LeafNodes);

 

  // Create the point-to-point link helpers

  PointToPointHelper pointToPointRouter;

  pointToPointRouter.SetDeviceAttribute  ("DataRate", StringValue ("1Mbps"));

  pointToPointRouter.SetChannelAttribute ("Delay", StringValue ("1ms"));

  PointToPointHelper pointToPointLeaf;

  pointToPointLeaf.SetDeviceAttribute    ("DataRate", StringValue ("10Mbps"));

  pointToPointLeaf.SetChannelAttribute   ("Delay", StringValue ("1ms"));

 

  NodeContainer router_nodes;

  router_nodes.Add (router_0);

  router_nodes.Add (router_1);

  NetDeviceContainer bottlelinkDevices = pointToPointRouter.Install (router_nodes);

  queueDiscs = tch.Install (bottlelinkDevices.Get(0));

  Ipv4AddressHelper ipv4;

  ipv4.SetBase ("10.0.0.0", "255.255.255.0");

  Ipv4InterfaceContainer bottlelinkIface = ipv4.Assign (bottlelinkDevices);

  

  NetDeviceContainer leftlinkDevices[nLeaf];

  NetDeviceContainer rightlinkDevices[nLeaf];

  Ipv4InterfaceContainer leftlinkIface[nLeaf];

  Ipv4InterfaceContainer rightlinkIface[nLeaf];

  NodeContainer leftside_nodes[nLeaf];

  NodeContainer rightside_nodes[nLeaf];

  std::string ip;

  for (uint32_t i=0 ; i <nLeaf; i++) {

    leftside_nodes[i].Add (router_0);

    leftside_nodes[i].Add (LeafNodes.Get(i));

    leftlinkDevices[i].Add(pointToPointLeaf.Install (leftside_nodes[i]));

    ip = "10.0." + lexical_cast< std::string >( i + 1 ) +".0";

    //std::cout << "ip:" << ip << std::endl;

    ipv4.SetBase (ns3::Ipv4Address(ip.c_str()), "255.255.255.0");

    leftlinkIface[i].Add(ipv4.Assign (leftlinkDevices[i]));

 

    rightside_nodes[i].Add (router_1);

    rightside_nodes[i].Add (LeafNodes.Get(nLeaf+i));

    rightlinkDevices[i].Add(pointToPointLeaf.Install (rightside_nodes[i]));

    ip = "10.1." + lexical_cast< std::string >( i + 1 ) +".0";

    //std::cout << "ip:" << ip << std::endl;

    ipv4.SetBase (ns3::Ipv4Address(ip.c_str()), "255.255.255.0");

    rightlinkIface[i].Add(ipv4.Assign (rightlinkDevices[i]));

  }

 

  // Set up the actual simulation

  Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

 

  /* Generate Application. */

  ApplicationContainer sinkApp[nLeaf];

  ApplicationContainer sourceApp[nLeaf];

  Ptr<PacketSink> sink[nLeaf];                   /* Pointer to the packet sink application */

  for (uint32_t i=0 ; i <nLeaf; i++) {

    PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), 9+i));

    sinkApp[i] = sinkHelper.Install (LeafNodes.Get(nLeaf+i));

    sink[i] = StaticCast<PacketSink> (sinkApp[i].Get (0));

 

    //std::cout << "destination ip:" << rightlinkIface[i].GetAddress (1) << std::endl;

    BulkSendHelper source ("ns3::TcpSocketFactory", (InetSocketAddress (rightlinkIface[i].GetAddress (1), 9+i)));

    source.SetAttribute ("MaxBytes", UintegerValue (0));

    sourceApp[i] = source.Install (LeafNodes.Get(i));

 

    // To differentiate each applications starting time

    double min = 0.0;

    double max = 1.0;

    Ptr<UniformRandomVariable> x = CreateObject<UniformRandomVariable> ();

    x->SetAttribute ("Min", DoubleValue (min));

    x->SetAttribute ("Max", DoubleValue (max));

    double differ_value = x->GetValue ();

    sinkApp[i].Start (Seconds (0.0));

    sourceApp[i].Start (Seconds (0.1 + differ_value));

  }

 

  FlowMonitorHelper flowmon;

  Ptr<FlowMonitor> monitor = flowmon.InstallAll();

  double single_throughput = 0;

  double total_throughput = 0;

 

  Simulator::Schedule (MilliSeconds (1), &PrintCurrentQueueSize);

 

  Simulator::Stop (Seconds (11.0));

  Simulator::Run ();

 

  Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmon.GetClassifier ());

  std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();

  for(std::map<FlowId, FlowMonitor::FlowStats>::const_iterator set = stats.begin(); set != stats.end(); set++)

  {

    single_throughput = set->second.rxBytes * 8.0 / (set->second.timeLastRxPacket.GetSeconds () - set->second.timeFirstRxPacket.GetSeconds ()) / 1000;

   

    Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(set->first);

 

    Ipv4Address ip1("10.0.0.0");

    Ipv4Address ip2=t.sourceAddress.CombineMask("255.255.0.0");

    if(ip1==ip2)

      total_throughput += single_throughput;

  

    //std::cout << "Flow " << set->first << " (" << t.sourceAddress << " -> " << t.destinationAddress << "), throughput: " << single_throughput << "kbps" << std::endl;

   

  }

  //std::cout << "Total throughput (from left to right): " << total_throughput << "Kbps" << std::endl;

    

  Simulator::Destroy ();

  return 0;

}

 

Execution

 

 

 

Back to NS3 Learning Guide

Last Modified: 2022/2/18 done

 

[Author]

Dr. Chih-Heng Ke

Department of Computer Science and Information Engineering, National Quemoy University, Kinmen, Taiwan

Email: smallko@gmail.com