A Discrete-Event Network Simulator
API
pie-example.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 NITK Surathkal
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Authors: Shravya Ks <shravya.ks0@gmail.com>
18  * Smriti Murali <m.smriti.95@gmail.com>
19  * Mohit P. Tahiliani <tahiliani@nitk.edu.in>
20  *
21  */
22 
34 #include "ns3/applications-module.h"
35 #include "ns3/core-module.h"
36 #include "ns3/flow-monitor-helper.h"
37 #include "ns3/internet-module.h"
38 #include "ns3/network-module.h"
39 #include "ns3/point-to-point-module.h"
40 #include "ns3/traffic-control-module.h"
41 
42 using namespace ns3;
43 
44 NS_LOG_COMPONENT_DEFINE("PieExample");
45 
46 uint32_t checkTimes;
48 
49 // The times
56 
62 
68 
69 std::stringstream filePlotQueueDisc;
70 std::stringstream filePlotQueueDiscAvg;
71 
72 void
74 {
75  uint32_t qSize = queue->GetCurrentSize().GetValue();
76 
77  avgQueueDiscSize += qSize;
78  checkTimes++;
79 
80  // check queue disc size every 1/100 of a second
82 
83  std::ofstream fPlotQueueDisc(filePlotQueueDisc.str(), std::ios::out | std::ios::app);
84  fPlotQueueDisc << Simulator::Now().GetSeconds() << " " << qSize << std::endl;
85  fPlotQueueDisc.close();
86 
87  std::ofstream fPlotQueueDiscAvg(filePlotQueueDiscAvg.str(), std::ios::out | std::ios::app);
88  fPlotQueueDiscAvg << Simulator::Now().GetSeconds() << " " << avgQueueDiscSize / checkTimes
89  << std::endl;
90  fPlotQueueDiscAvg.close();
91 }
92 
93 void
95 {
96  // SINK is in the right side
97  uint16_t port = 50000;
98  Address sinkLocalAddress(InetSocketAddress(Ipv4Address::GetAny(), port));
99  PacketSinkHelper sinkHelper("ns3::TcpSocketFactory", sinkLocalAddress);
100  ApplicationContainer sinkApp = sinkHelper.Install(n3n4.Get(1));
101  sinkApp.Start(Seconds(sink_start_time));
102  sinkApp.Stop(Seconds(sink_stop_time));
103 
104  // Connection one
105  // Clients are in left side
106  /*
107  * Create the OnOff applications to send TCP to the server
108  * onoffhelper is a client that send data to TCP destination
109  */
110  OnOffHelper clientHelper1("ns3::TcpSocketFactory", Address());
111  clientHelper1.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
112  clientHelper1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
113  clientHelper1.SetAttribute("PacketSize", UintegerValue(1000));
114  clientHelper1.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
115 
116  // Connection two
117  OnOffHelper clientHelper2("ns3::TcpSocketFactory", Address());
118  clientHelper2.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
119  clientHelper2.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
120  clientHelper2.SetAttribute("PacketSize", UintegerValue(1000));
121  clientHelper2.SetAttribute("DataRate", DataRateValue(DataRate("10Mb/s")));
122 
123  ApplicationContainer clientApps1;
125  clientHelper1.SetAttribute("Remote", remoteAddress);
126  clientApps1.Add(clientHelper1.Install(n0n2.Get(0)));
127  clientApps1.Start(Seconds(client_start_time));
128  clientApps1.Stop(Seconds(client_stop_time));
129 
130  ApplicationContainer clientApps2;
131  clientHelper2.SetAttribute("Remote", remoteAddress);
132  clientApps2.Add(clientHelper2.Install(n1n2.Get(0)));
133  clientApps2.Start(Seconds(client_start_time));
134  clientApps2.Stop(Seconds(client_stop_time));
135 }
136 
137 int
138 main(int argc, char* argv[])
139 {
140  LogComponentEnable("PieQueueDisc", LOG_LEVEL_INFO);
141 
142  std::string pieLinkDataRate = "1.5Mbps";
143  std::string pieLinkDelay = "20ms";
144 
145  std::string pathOut;
146  bool writeForPlot = false;
147  bool writePcap = false;
148  bool flowMonitor = false;
149 
150  bool printPieStats = true;
151 
152  global_start_time = 0.0;
155  global_stop_time = 7.0;
158 
159  // Configuration and command line parameter parsing
160  // Will only save in the directory if enable opts below
161  pathOut = "."; // Current directory
162  CommandLine cmd(__FILE__);
163  cmd.AddValue("pathOut",
164  "Path to save results from --writeForPlot/--writePcap/--writeFlowMonitor",
165  pathOut);
166  cmd.AddValue("writeForPlot", "<0/1> to write results for plot (gnuplot)", writeForPlot);
167  cmd.AddValue("writePcap", "<0/1> to write results in pcapfile", writePcap);
168  cmd.AddValue("writeFlowMonitor",
169  "<0/1> to enable Flow Monitor and write their results",
170  flowMonitor);
171 
172  cmd.Parse(argc, argv);
173 
174  NS_LOG_INFO("Create nodes");
175  NodeContainer c;
176  c.Create(6);
177  Names::Add("N0", c.Get(0));
178  Names::Add("N1", c.Get(1));
179  Names::Add("N2", c.Get(2));
180  Names::Add("N3", c.Get(3));
181  Names::Add("N4", c.Get(4));
182  Names::Add("N5", c.Get(5));
183  n0n2 = NodeContainer(c.Get(0), c.Get(2));
184  n1n2 = NodeContainer(c.Get(1), c.Get(2));
185  n2n3 = NodeContainer(c.Get(2), c.Get(3));
186  n3n4 = NodeContainer(c.Get(3), c.Get(4));
187  n3n5 = NodeContainer(c.Get(3), c.Get(5));
188 
189  Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::TcpNewReno"));
190  // 42 = headers size
191  Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(1000 - 42));
192  Config::SetDefault("ns3::TcpSocket::DelAckCount", UintegerValue(1));
193  GlobalValue::Bind("ChecksumEnabled", BooleanValue(false));
194 
195  uint32_t meanPktSize = 1000;
196 
197  // PIE params
198  NS_LOG_INFO("Set PIE params");
199  Config::SetDefault("ns3::PieQueueDisc::MaxSize", StringValue("100p"));
200  Config::SetDefault("ns3::PieQueueDisc::MeanPktSize", UintegerValue(meanPktSize));
201  Config::SetDefault("ns3::PieQueueDisc::DequeueThreshold", UintegerValue(10000));
202  Config::SetDefault("ns3::PieQueueDisc::QueueDelayReference", TimeValue(Seconds(0.02)));
203  Config::SetDefault("ns3::PieQueueDisc::MaxBurstAllowance", TimeValue(Seconds(0.1)));
204 
205  NS_LOG_INFO("Install internet stack on all nodes.");
207  internet.Install(c);
208 
209  TrafficControlHelper tchPfifo;
210  uint16_t handle = tchPfifo.SetRootQueueDisc("ns3::PfifoFastQueueDisc");
211  tchPfifo.AddInternalQueues(handle, 3, "ns3::DropTailQueue", "MaxSize", StringValue("1000p"));
212 
213  TrafficControlHelper tchPie;
214  tchPie.SetRootQueueDisc("ns3::PieQueueDisc");
215 
216  NS_LOG_INFO("Create channels");
218 
219  NetDeviceContainer devn0n2;
220  NetDeviceContainer devn1n2;
221  NetDeviceContainer devn2n3;
222  NetDeviceContainer devn3n4;
223  NetDeviceContainer devn3n5;
224 
225  QueueDiscContainer queueDiscs;
226 
227  p2p.SetQueue("ns3::DropTailQueue");
228  p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
229  p2p.SetChannelAttribute("Delay", StringValue("2ms"));
230  devn0n2 = p2p.Install(n0n2);
231  tchPfifo.Install(devn0n2);
232 
233  p2p.SetQueue("ns3::DropTailQueue");
234  p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
235  p2p.SetChannelAttribute("Delay", StringValue("3ms"));
236  devn1n2 = p2p.Install(n1n2);
237  tchPfifo.Install(devn1n2);
238 
239  p2p.SetQueue("ns3::DropTailQueue");
240  p2p.SetDeviceAttribute("DataRate", StringValue(pieLinkDataRate));
241  p2p.SetChannelAttribute("Delay", StringValue(pieLinkDelay));
242  devn2n3 = p2p.Install(n2n3);
243  // only backbone link has PIE queue disc
244  queueDiscs = tchPie.Install(devn2n3);
245 
246  p2p.SetQueue("ns3::DropTailQueue");
247  p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
248  p2p.SetChannelAttribute("Delay", StringValue("4ms"));
249  devn3n4 = p2p.Install(n3n4);
250  tchPfifo.Install(devn3n4);
251 
252  p2p.SetQueue("ns3::DropTailQueue");
253  p2p.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
254  p2p.SetChannelAttribute("Delay", StringValue("5ms"));
255  devn3n5 = p2p.Install(n3n5);
256  tchPfifo.Install(devn3n5);
257 
258  NS_LOG_INFO("Assign IP Addresses");
260 
261  ipv4.SetBase("10.1.1.0", "255.255.255.0");
262  i0i2 = ipv4.Assign(devn0n2);
263 
264  ipv4.SetBase("10.1.2.0", "255.255.255.0");
265  i1i2 = ipv4.Assign(devn1n2);
266 
267  ipv4.SetBase("10.1.3.0", "255.255.255.0");
268  i2i3 = ipv4.Assign(devn2n3);
269 
270  ipv4.SetBase("10.1.4.0", "255.255.255.0");
271  i3i4 = ipv4.Assign(devn3n4);
272 
273  ipv4.SetBase("10.1.5.0", "255.255.255.0");
274  i3i5 = ipv4.Assign(devn3n5);
275 
276  // Set up the routing
278 
279  BuildAppsTest();
280 
281  if (writePcap)
282  {
283  PointToPointHelper ptp;
284  std::stringstream stmp;
285  stmp << pathOut << "/pie";
286  ptp.EnablePcapAll(stmp.str());
287  }
288 
289  Ptr<FlowMonitor> flowmon;
290  if (flowMonitor)
291  {
292  FlowMonitorHelper flowmonHelper;
293  flowmon = flowmonHelper.InstallAll();
294  }
295 
296  if (writeForPlot)
297  {
298  filePlotQueueDisc << pathOut << "/"
299  << "pie-queue-disc.plotme";
300  filePlotQueueDiscAvg << pathOut << "/"
301  << "pie-queue-disc_avg.plotme";
302 
303  remove(filePlotQueueDisc.str().c_str());
304  remove(filePlotQueueDiscAvg.str().c_str());
305  Ptr<QueueDisc> queue = queueDiscs.Get(0);
307  }
308 
310  Simulator::Run();
311 
312  QueueDisc::Stats st = queueDiscs.Get(0)->GetStats();
313 
315  {
316  std::cout << "There should be no drops due to queue full." << std::endl;
317  exit(1);
318  }
319 
320  if (flowMonitor)
321  {
322  std::stringstream stmp;
323  stmp << pathOut << "/pie.flowmon";
324 
325  flowmon->SerializeToXmlFile(stmp.str(), false, false);
326  }
327 
328  if (printPieStats)
329  {
330  std::cout << "*** PIE stats from Node 2 queue ***" << std::endl;
331  std::cout << "\t " << st.GetNDroppedPackets(PieQueueDisc::UNFORCED_DROP)
332  << " drops due to prob mark" << std::endl;
333  std::cout << "\t " << st.GetNDroppedPackets(PieQueueDisc::FORCED_DROP)
334  << " drops due to queue limits" << std::endl;
335  }
336 
338 
339  return 0;
340 }
a polymophic address class
Definition: address.h:101
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
void Add(ApplicationContainer other)
Append the contents of another ApplicationContainer to the end of this container.
Parse command-line arguments.
Definition: command-line.h:232
Helper to enable IP flow monitoring on a set of Nodes.
Ptr< FlowMonitor > InstallAll()
Enable flow monitoring on all nodes.
static void Bind(std::string name, const AttributeValue &value)
Iterate over the set of GlobalValues until a matching name is found and then set its value with Globa...
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
static void Add(std::string name, Ptr< Object > object)
Add the association between the string "name" and the Ptr<Object> obj.
Definition: names.cc:775
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::OnOffApplication on a set of nodes.
Definition: on-off-helper.h:44
ApplicationContainer Install(NodeContainer c) const
Install an ns3::OnOffApplication on each node of the input container configured with all the attribut...
void SetAttribute(std::string name, const AttributeValue &value)
Helper function used to set the underlying application attributes.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
void EnablePcapAll(std::string prefix, bool promiscuous=false)
Enable pcap output on each device (which is of the appropriate type) in the set of all nodes created ...
static constexpr const char * UNFORCED_DROP
Early probability drops: proactive.
static constexpr const char * FORCED_DROP
Drops due to queue limit: reactive.
Build a set of PointToPointNetDevice objects.
Holds a vector of ns3::QueueDisc pointers.
Ptr< QueueDisc > Get(std::size_t i) const
Get the Ptr<QueueDisc> stored in this container at a given index.
QueueSize GetCurrentSize() const
Get the current size of the queue disc in bytes, if operating in bytes mode, or packets,...
Definition: queue-disc.cc:515
const Stats & GetStats()
Retrieve all the collected statistics.
Definition: queue-disc.cc:412
uint32_t GetValue() const
Get the underlying value.
Definition: queue-size.cc:183
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition: simulator.cc:142
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
static void Run()
Run the simulation.
Definition: simulator.cc:178
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition: simulator.h:605
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition: simulator.cc:186
Hold variables of type string.
Definition: string.h:56
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:403
Build a set of QueueDisc objects.
QueueDiscContainer Install(NetDeviceContainer c)
uint16_t SetRootQueueDisc(const std::string &type, Args &&... args)
Helper function used to set a root queue disc of the given type and with the given attributes.
void AddInternalQueues(uint16_t handle, uint16_t count, std::string type, Args &&... args)
Helper function used to add the given number of internal queues (of the given type and with the given...
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:44
void SetDefault(std::string name, const AttributeValue &value)
Definition: config.cc:890
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
void(* DataRate)(DataRate oldValue, DataRate newValue)
TracedValue callback signature for DataRate.
Definition: data-rate.h:327
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void LogComponentEnable(const std::string &name, LogLevel level)
Enable the logging output associated with that log component.
Definition: log.cc:302
@ LOG_LEVEL_INFO
LOG_INFO and above.
Definition: log.h:104
cmd
Definition: second.py:40
Ipv4InterfaceContainer i0i2
Definition: pie-example.cc:63
std::stringstream filePlotQueueDisc
Definition: pie-example.cc:69
void BuildAppsTest()
Definition: pie-example.cc:94
double client_start_time
Definition: pie-example.cc:54
double sink_stop_time
Definition: pie-example.cc:53
double sink_start_time
Definition: pie-example.cc:52
double global_stop_time
Definition: pie-example.cc:51
std::stringstream filePlotQueueDiscAvg
Definition: pie-example.cc:70
NodeContainer n2n3
Definition: pie-example.cc:59
void CheckQueueDiscSize(Ptr< QueueDisc > queue)
Definition: pie-example.cc:73
NodeContainer n1n2
Definition: pie-example.cc:58
double avgQueueDiscSize
Definition: pie-example.cc:47
NodeContainer n3n4
Definition: pie-example.cc:60
double global_start_time
Definition: pie-example.cc:50
Ipv4InterfaceContainer i1i2
Definition: pie-example.cc:64
Ipv4InterfaceContainer i3i4
Definition: pie-example.cc:66
NodeContainer n0n2
Definition: pie-example.cc:57
double client_stop_time
Definition: pie-example.cc:55
uint32_t checkTimes
Definition: pie-example.cc:44
NodeContainer n3n5
Definition: pie-example.cc:61
Ipv4InterfaceContainer i3i5
Definition: pie-example.cc:67
Ipv4InterfaceContainer i2i3
Definition: pie-example.cc:65
Structure that keeps the queue disc statistics.
Definition: queue-disc.h:188
uint32_t GetNDroppedPackets(std::string reason) const
Get the number of packets dropped for the given reason.
Definition: queue-disc.cc:111