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
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