OLD | NEW |
(Empty) | |
| 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| 2 /* |
| 3 * Copyright (c) 2017 NITK Surathkal |
| 4 * |
| 5 * This program is free software; you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 2 as |
| 7 * published by the Free Software Foundation; |
| 8 * |
| 9 * This program is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with this program; if not, write to the Free Software |
| 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 17 * |
| 18 * Author: Shravya K.S. <shravya.ks0@gmail.com> |
| 19 * |
| 20 */ |
| 21 |
| 22 /** Network topology |
| 23 * |
| 24 * 10Mb/s, 0ms 10Mb/s, 0ms |
| 25 * n0--------------| |---------------n4 |
| 26 * | 1.5Mbps, 20ms | |
| 27 * n2------------------n3 |
| 28 * 10Mb/s, 0ms | QueueLimit = 100 | 10Mb/s, 0ms |
| 29 * n1--------------| |---------------n5 |
| 30 * |
| 31 */ |
| 32 |
| 33 #include "ns3/core-module.h" |
| 34 #include "ns3/network-module.h" |
| 35 #include "ns3/internet-module.h" |
| 36 #include "ns3/flow-monitor-helper.h" |
| 37 #include "ns3/point-to-point-module.h" |
| 38 #include "ns3/applications-module.h" |
| 39 #include "ns3/traffic-control-module.h" |
| 40 |
| 41 using namespace ns3; |
| 42 |
| 43 NS_LOG_COMPONENT_DEFINE ("DualQCoupledPiSquareExample"); |
| 44 |
| 45 uint32_t checkTimes; |
| 46 double avgQueueDiscSize; |
| 47 |
| 48 // The times |
| 49 double global_start_time; |
| 50 double global_stop_time; |
| 51 double sink_start_time; |
| 52 double sink_stop_time; |
| 53 double client_start_time; |
| 54 double client_stop_time; |
| 55 |
| 56 NodeContainer n0n2; |
| 57 NodeContainer n1n2; |
| 58 NodeContainer n2n3; |
| 59 NodeContainer n3n4; |
| 60 NodeContainer n3n5; |
| 61 |
| 62 Ipv4InterfaceContainer i0i2; |
| 63 Ipv4InterfaceContainer i1i2; |
| 64 Ipv4InterfaceContainer i2i3; |
| 65 Ipv4InterfaceContainer i3i4; |
| 66 Ipv4InterfaceContainer i3i5; |
| 67 |
| 68 std::stringstream filePlotQueueDisc; |
| 69 std::stringstream filePlotQueueDiscAvg; |
| 70 |
| 71 void |
| 72 CheckQueueDiscSize (Ptr<QueueDisc> queue) |
| 73 { |
| 74 uint32_t qSize = StaticCast<DualQCoupledPiSquareQueueDisc> (queue)->GetQueueSi
ze (); |
| 75 |
| 76 avgQueueDiscSize += qSize; |
| 77 checkTimes++; |
| 78 |
| 79 // check queue disc size every 1/100 of a second |
| 80 Simulator::Schedule (Seconds (0.01), &CheckQueueDiscSize, queue); |
| 81 |
| 82 std::ofstream fPlotQueueDisc (filePlotQueueDisc.str ().c_str (), std::ios::out
| std::ios::app); |
| 83 fPlotQueueDisc << Simulator::Now ().GetSeconds () << " " << qSize << std::endl
; |
| 84 fPlotQueueDisc.close (); |
| 85 |
| 86 std::ofstream fPlotQueueDiscAvg (filePlotQueueDiscAvg.str ().c_str (), std::io
s::out | std::ios::app); |
| 87 fPlotQueueDiscAvg << Simulator::Now ().GetSeconds () << " " << avgQueueDiscSiz
e / checkTimes << std::endl; |
| 88 fPlotQueueDiscAvg.close (); |
| 89 } |
| 90 |
| 91 void |
| 92 BuildAppsTest () |
| 93 { |
| 94 // SINK1 is in the right side |
| 95 uint16_t port1 = 50000; |
| 96 Address sinkLocalAddress1 (InetSocketAddress (Ipv4Address::GetAny (), port1)); |
| 97 PacketSinkHelper sinkHelper1 ("ns3::TcpSocketFactory", sinkLocalAddress1); |
| 98 ApplicationContainer sinkApp1 = sinkHelper1.Install (n3n4.Get (1)); |
| 99 sinkApp1.Start (Seconds (sink_start_time)); |
| 100 sinkApp1.Stop (Seconds (sink_stop_time)); |
| 101 |
| 102 // SINK2 is in the right side |
| 103 uint16_t port2 = 50001; |
| 104 Address sinkLocalAddress2 (InetSocketAddress (Ipv4Address::GetAny (), port2)); |
| 105 PacketSinkHelper sinkHelper2 ("ns3::TcpSocketFactory", sinkLocalAddress2); |
| 106 ApplicationContainer sinkApp2 = sinkHelper2.Install (n3n5.Get (1)); |
| 107 sinkApp2.Start (Seconds (sink_start_time)); |
| 108 sinkApp2.Stop (Seconds (sink_stop_time)); |
| 109 |
| 110 // Configure Classic traffic from Node 0 to Node 5 |
| 111 // Configure L4S traffic from Node 1 to Node 4 |
| 112 Config::Set ("/NodeList/0/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpNew
Reno::GetTypeId ())); |
| 113 Config::Set ("/NodeList/1/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpDct
cp::GetTypeId ())); |
| 114 Config::Set ("/NodeList/4/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpNew
Reno::GetTypeId ())); |
| 115 Config::Set ("/NodeList/5/$ns3::TcpL4Protocol/SocketType", TypeIdValue (TcpDct
cp::GetTypeId ())); |
| 116 |
| 117 |
| 118 // Clients are in left side |
| 119 /* |
| 120 * Create the OnOff applications to send TCP to the server |
| 121 * onoffhelper is a client that sends data to TCP destination |
| 122 */ |
| 123 |
| 124 // Connection one |
| 125 OnOffHelper clientHelper1 ("ns3::TcpSocketFactory", Address ()); |
| 126 clientHelper1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariabl
e[Constant=1]")); |
| 127 clientHelper1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariab
le[Constant=0]")); |
| 128 clientHelper1.SetAttribute ("PacketSize", UintegerValue (1000)); |
| 129 clientHelper1.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s"))); |
| 130 |
| 131 // Connection two |
| 132 OnOffHelper clientHelper2 ("ns3::TcpSocketFactory", Address ()); |
| 133 clientHelper2.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariabl
e[Constant=1]")); |
| 134 clientHelper2.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariab
le[Constant=0]")); |
| 135 clientHelper2.SetAttribute ("PacketSize", UintegerValue (1000)); |
| 136 clientHelper2.SetAttribute ("DataRate", DataRateValue (DataRate ("10Mb/s"))); |
| 137 |
| 138 ApplicationContainer clientApps1; |
| 139 AddressValue remoteAddress1 (InetSocketAddress (i3i4.GetAddress (1), port1)); |
| 140 clientHelper1.SetAttribute ("Remote", remoteAddress1); |
| 141 clientApps1.Add (clientHelper1.Install (n0n2.Get (0))); |
| 142 clientApps1.Start (Seconds (client_start_time)); |
| 143 clientApps1.Stop (Seconds (client_stop_time)); |
| 144 |
| 145 ApplicationContainer clientApps2; |
| 146 AddressValue remoteAddress2 (InetSocketAddress (i3i5.GetAddress (1), port2)); |
| 147 clientHelper2.SetAttribute ("Remote", remoteAddress2); |
| 148 clientApps2.Add (clientHelper2.Install (n1n2.Get (0))); |
| 149 clientApps2.Start (Seconds (client_start_time)); |
| 150 clientApps2.Stop (Seconds (client_stop_time)); |
| 151 } |
| 152 |
| 153 int |
| 154 main (int argc, char *argv[]) |
| 155 { |
| 156 LogComponentEnable ("DualQCoupledPiSquareQueueDisc", LOG_LEVEL_INFO); |
| 157 |
| 158 std::string dualQCoupledPiSquareLinkDataRate = "1.5Mbps"; |
| 159 std::string dualQCoupledPiSquareLinkDelay = "20ms"; |
| 160 |
| 161 std::string pathOut; |
| 162 bool writeForPlot = false; |
| 163 bool writePcap = false; |
| 164 bool flowMonitor = false; |
| 165 |
| 166 bool printDualQCoupledPiSquareStats = true; |
| 167 |
| 168 global_start_time = 0.0; |
| 169 sink_start_time = global_start_time; |
| 170 client_start_time = global_start_time + 1.5; |
| 171 global_stop_time = 20.0; |
| 172 sink_stop_time = global_stop_time + 3.0; |
| 173 client_stop_time = global_stop_time - 2.0; |
| 174 |
| 175 // Configuration and command line parameter parsing |
| 176 // Will only save in the directory if enable opts below |
| 177 pathOut = "."; // Current directory |
| 178 CommandLine cmd; |
| 179 cmd.AddValue ("pathOut", "Path to save results from --writeForPlot/--writePcap
/--writeFlowMonitor", pathOut); |
| 180 cmd.AddValue ("writeForPlot", "<0/1> to write results for plot (gnuplot)", wri
teForPlot); |
| 181 cmd.AddValue ("writePcap", "<0/1> to write results in pcapfile", writePcap); |
| 182 cmd.AddValue ("writeFlowMonitor", "<0/1> to enable Flow Monitor and write thei
r results", flowMonitor); |
| 183 |
| 184 cmd.Parse (argc, argv); |
| 185 |
| 186 NS_LOG_INFO ("Create nodes"); |
| 187 NodeContainer c; |
| 188 c.Create (6); |
| 189 Names::Add ( "N0", c.Get (0)); |
| 190 Names::Add ( "N1", c.Get (1)); |
| 191 Names::Add ( "N2", c.Get (2)); |
| 192 Names::Add ( "N3", c.Get (3)); |
| 193 Names::Add ( "N4", c.Get (4)); |
| 194 Names::Add ( "N5", c.Get (5)); |
| 195 n0n2 = NodeContainer (c.Get (0), c.Get (2)); |
| 196 n1n2 = NodeContainer (c.Get (1), c.Get (2)); |
| 197 n2n3 = NodeContainer (c.Get (2), c.Get (3)); |
| 198 n3n4 = NodeContainer (c.Get (3), c.Get (4)); |
| 199 n3n5 = NodeContainer (c.Get (3), c.Get (5)); |
| 200 |
| 201 Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (1000)); |
| 202 Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (1)); |
| 203 Config::SetDefault ("ns3::TcpSocketBase::UseEcn", BooleanValue (true)); |
| 204 GlobalValue::Bind ("ChecksumEnabled", BooleanValue (false)); |
| 205 |
| 206 uint32_t meanPktSize = 1000; |
| 207 |
| 208 // DualQCoupledPiSquare parameters |
| 209 NS_LOG_INFO ("Set DualQCoupledPiSquare params"); |
| 210 Config::SetDefault ("ns3::DualQCoupledPiSquareQueueDisc::Mode", StringValue ("
QUEUE_DISC_MODE_PACKETS")); |
| 211 Config::SetDefault ("ns3::DualQCoupledPiSquareQueueDisc::MeanPktSize", Uintege
rValue (meanPktSize)); |
| 212 Config::SetDefault ("ns3::DualQCoupledPiSquareQueueDisc::QueueLimit", Uinteger
Value (100)); |
| 213 |
| 214 NS_LOG_INFO ("Install internet stack on all nodes."); |
| 215 InternetStackHelper internet; |
| 216 internet.Install (c); |
| 217 |
| 218 TrafficControlHelper tchPfifo; |
| 219 uint16_t handle = tchPfifo.SetRootQueueDisc ("ns3::PfifoFastQueueDisc"); |
| 220 tchPfifo.AddInternalQueues (handle, 3, "ns3::DropTailQueue", "MaxPackets", Uin
tegerValue (1000)); |
| 221 |
| 222 TrafficControlHelper tchDualQCoupledPiSquare; |
| 223 handle = tchDualQCoupledPiSquare.SetRootQueueDisc ("ns3::DualQCoupledPiSquareQ
ueueDisc"); |
| 224 tchDualQCoupledPiSquare.AddInternalQueues (handle, 2, "ns3::DropTailQueue", "M
axPackets", UintegerValue (1000)); |
| 225 |
| 226 NS_LOG_INFO ("Create channels"); |
| 227 PointToPointHelper p2p; |
| 228 |
| 229 NetDeviceContainer devn0n2; |
| 230 NetDeviceContainer devn1n2; |
| 231 NetDeviceContainer devn2n3; |
| 232 NetDeviceContainer devn3n4; |
| 233 NetDeviceContainer devn3n5; |
| 234 |
| 235 QueueDiscContainer queueDiscs; |
| 236 |
| 237 p2p.SetQueue ("ns3::DropTailQueue"); |
| 238 p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); |
| 239 p2p.SetChannelAttribute ("Delay", StringValue ("0ms")); |
| 240 devn0n2 = p2p.Install (n0n2); |
| 241 tchPfifo.Install (devn0n2); |
| 242 |
| 243 p2p.SetQueue ("ns3::DropTailQueue"); |
| 244 p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); |
| 245 p2p.SetChannelAttribute ("Delay", StringValue ("0ms")); |
| 246 devn1n2 = p2p.Install (n1n2); |
| 247 tchPfifo.Install (devn1n2); |
| 248 |
| 249 p2p.SetQueue ("ns3::DropTailQueue"); |
| 250 p2p.SetDeviceAttribute ("DataRate", StringValue (dualQCoupledPiSquareLinkDataR
ate)); |
| 251 p2p.SetChannelAttribute ("Delay", StringValue (dualQCoupledPiSquareLinkDelay))
; |
| 252 devn2n3 = p2p.Install (n2n3); |
| 253 // only backbone link has DualQCoupledPiSquare queue disc |
| 254 queueDiscs = tchDualQCoupledPiSquare.Install (devn2n3); |
| 255 |
| 256 p2p.SetQueue ("ns3::DropTailQueue"); |
| 257 p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); |
| 258 p2p.SetChannelAttribute ("Delay", StringValue ("0ms")); |
| 259 devn3n4 = p2p.Install (n3n4); |
| 260 tchPfifo.Install (devn3n4); |
| 261 |
| 262 p2p.SetQueue ("ns3::DropTailQueue"); |
| 263 p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps")); |
| 264 p2p.SetChannelAttribute ("Delay", StringValue ("0ms")); |
| 265 devn3n5 = p2p.Install (n3n5); |
| 266 tchPfifo.Install (devn3n5); |
| 267 |
| 268 NS_LOG_INFO ("Assign IP Addresses"); |
| 269 Ipv4AddressHelper ipv4; |
| 270 |
| 271 ipv4.SetBase ("10.1.1.0", "255.255.255.0"); |
| 272 i0i2 = ipv4.Assign (devn0n2); |
| 273 |
| 274 ipv4.SetBase ("10.1.2.0", "255.255.255.0"); |
| 275 i1i2 = ipv4.Assign (devn1n2); |
| 276 |
| 277 ipv4.SetBase ("10.1.3.0", "255.255.255.0"); |
| 278 i2i3 = ipv4.Assign (devn2n3); |
| 279 |
| 280 ipv4.SetBase ("10.1.4.0", "255.255.255.0"); |
| 281 i3i4 = ipv4.Assign (devn3n4); |
| 282 |
| 283 ipv4.SetBase ("10.1.5.0", "255.255.255.0"); |
| 284 i3i5 = ipv4.Assign (devn3n5); |
| 285 |
| 286 // Set up the routing |
| 287 Ipv4GlobalRoutingHelper::PopulateRoutingTables (); |
| 288 |
| 289 BuildAppsTest (); |
| 290 |
| 291 if (writePcap) |
| 292 { |
| 293 PointToPointHelper ptp; |
| 294 std::stringstream stmp; |
| 295 stmp << pathOut << "/dual-q-coupled-pi-square"; |
| 296 ptp.EnablePcapAll (stmp.str ().c_str ()); |
| 297 } |
| 298 |
| 299 Ptr<FlowMonitor> flowmon; |
| 300 if (flowMonitor) |
| 301 { |
| 302 FlowMonitorHelper flowmonHelper; |
| 303 flowmon = flowmonHelper.InstallAll (); |
| 304 } |
| 305 |
| 306 if (writeForPlot) |
| 307 { |
| 308 filePlotQueueDisc << pathOut << "/" << "dual-q-coupled-pi-square-queue-dis
c.plotme"; |
| 309 filePlotQueueDiscAvg << pathOut << "/" << "dual-q-coupled-pi-square-queue-
disc_avg.plotme"; |
| 310 |
| 311 remove (filePlotQueueDisc.str ().c_str ()); |
| 312 remove (filePlotQueueDiscAvg.str ().c_str ()); |
| 313 Ptr<QueueDisc> queue = queueDiscs.Get (0); |
| 314 Simulator::ScheduleNow (&CheckQueueDiscSize, queue); |
| 315 } |
| 316 |
| 317 Simulator::Stop (Seconds (sink_stop_time)); |
| 318 Simulator::Run (); |
| 319 |
| 320 DualQCoupledPiSquareQueueDisc::Stats st = StaticCast<DualQCoupledPiSquareQueue
Disc> (queueDiscs.Get (0))->GetStats (); |
| 321 |
| 322 if (flowMonitor) |
| 323 { |
| 324 std::stringstream stmp; |
| 325 stmp << pathOut << "/dual-q-coupled-pi-square.flowmon"; |
| 326 |
| 327 flowmon->SerializeToXmlFile (stmp.str ().c_str (), false, false); |
| 328 } |
| 329 |
| 330 if (printDualQCoupledPiSquareStats) |
| 331 { |
| 332 std::cout << "*** DualQCoupledPiSquare stats from Node 2 queue ***" << std
::endl; |
| 333 std::cout << "\t " << st.unforcedClassicDrop << " Unforced drops (Classic
traffic)" << std::endl; |
| 334 std::cout << "\t " << st.unforcedClassicMark << " Unforced marks (Classic
traffic)" << std::endl; |
| 335 std::cout << "\t " << st.unforcedL4SMark << " Unforced marks (L4S traffic)
" << std::endl; |
| 336 std::cout << "\t " << st.forcedDrop << " Forced drops" << std::endl; |
| 337 } |
| 338 |
| 339 Simulator::Destroy (); |
| 340 return 0; |
| 341 } |
OLD | NEW |