diff --git a/examples/tcp/tcp-bbr-example.cc b/examples/tcp/tcp-bbr-example.cc index 571db943c..729c4b3fa 100644 --- a/examples/tcp/tcp-bbr-example.cc +++ b/examples/tcp/tcp-bbr-example.cc @@ -60,9 +60,15 @@ #include "ns3/point-to-point-module.h" #include "ns3/traffic-control-module.h" +#include + using namespace ns3; +using namespace ns3::SystemPath; std::string dir; +std::ofstream throughput; +std::ofstream queueSize; + uint32_t prev = 0; Time prevTime = Seconds(0); @@ -75,11 +81,9 @@ TraceThroughput(Ptr monitor) { auto itr = stats.begin(); Time curTime = Now(); - std::ofstream thr(dir + "/throughput.dat", std::ios::out | std::ios::app); - thr << curTime << " " - << 8 * (itr->second.txBytes - prev) / - (1000 * 1000 * (curTime.GetSeconds() - prevTime.GetSeconds())) - << std::endl; + throughput << curTime << " " + << 8 * (itr->second.txBytes - prev) / ((curTime - prevTime).ToDouble(Time::US)) + << std::endl; prevTime = curTime; prev = itr->second.txBytes; } @@ -92,9 +96,7 @@ CheckQueueSize(Ptr qd) { uint32_t qsize = qd->GetCurrentSize().GetValue(); Simulator::Schedule(Seconds(0.2), &CheckQueueSize, qd); - std::ofstream q(dir + "/queueSize.dat", std::ios::out | std::ios::app); - q << Simulator::Now().GetSeconds() << " " << qsize << std::endl; - q.close(); + queueSize << Simulator::Now().GetSeconds() << " " << qsize << std::endl; } // Trace congestion window @@ -146,6 +148,10 @@ main(int argc, char* argv[]) queueDisc = std::string("ns3::") + queueDisc; Config::SetDefault("ns3::TcpL4Protocol::SocketType", StringValue("ns3::" + tcpTypeId)); + + // The maximum send buffer size is set to 4194304 bytes (4MB) and the + // maximum receive buffer size is set to 6291456 bytes (6MB) in the Linux + // kernel. The same buffer sizes are used as default in this example. Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(4194304)); Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(6291456)); Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(10)); @@ -228,23 +234,20 @@ main(int argc, char* argv[]) // Create a new directory to store the output of the program dir = "bbr-results/" + currentTime + "/"; - std::string dirToSave = "mkdir -p " + dir; - if (system(dirToSave.c_str()) == -1) - { - exit(1); - } + MakeDirectories(dir); // The plotting scripts are provided in the following repository, if needed: // https://github.com/mohittahiliani/BBR-Validation/ // // Download 'PlotScripts' directory (which is inside ns-3 scripts directory) // from the link given above and place it in the ns-3 root directory. - // Uncomment the following three lines to generate plots for Congestion - // Window, sender side throughput and queue occupancy on the bottleneck link. + // Uncomment the following three lines to copy plot scripts for + // Congestion Window, sender side throughput and queue occupancy on the + // bottleneck link into the output directory. // - // system (("cp -R PlotScripts/gnuplotScriptCwnd " + dir).c_str ()); - // system (("cp -R PlotScripts/gnuplotScriptThroughput " + dir).c_str ()); - // system (("cp -R PlotScripts/gnuplotScriptQueueSize " + dir).c_str ()); + // std::filesystem::copy("PlotScripts/gnuplotScriptCwnd", dir); + // std::filesystem::copy("PlotScripts/gnuplotScriptThroughput", dir); + // std::filesystem::copy("PlotScripts/gnuplotScriptQueueSize", dir); // Trace the queue occupancy on the second interface of R1 tch.Uninstall(routers.Get(0)->GetDevice(1)); @@ -255,13 +258,17 @@ main(int argc, char* argv[]) // Generate PCAP traces if it is enabled if (enablePcap) { - if (system((dirToSave + "/pcap/").c_str()) == -1) - { - exit(1); - } + MakeDirectories(dir + "pcap/"); bottleneckLink.EnablePcapAll(dir + "/pcap/bbr", true); } + // Open files for writing throughput traces and queue size + throughput.open(dir + "/throughput.dat", std::ios::out); + queueSize.open(dir + "/queueSize.dat", std::ios::out); + + NS_ASSERT_MSG(throughput.is_open(), "Throughput file was not opened correctly"); + NS_ASSERT_MSG(queueSize.is_open(), "Queue size file was not opened correctly"); + // Check for dropped packets using Flow Monitor FlowMonitorHelper flowmon; Ptr monitor = flowmon.InstallAll(); @@ -271,5 +278,8 @@ main(int argc, char* argv[]) Simulator::Run(); Simulator::Destroy(); + throughput.close(); + queueSize.close(); + return 0; } diff --git a/examples/tcp/tcp-linux-reno.cc b/examples/tcp/tcp-linux-reno.cc index 96978f00c..85bbcde9c 100644 --- a/examples/tcp/tcp-linux-reno.cc +++ b/examples/tcp/tcp-linux-reno.cc @@ -52,6 +52,9 @@ std::string dir = "results/"; Time stopTime = Seconds(60); uint32_t segmentSize = 524; +std::ofstream fPlotQueue; +std::ofstream fPlotCwnd; + // Function to check queue length of Router 1 void CheckQueueSize(Ptr queue) @@ -60,19 +63,14 @@ CheckQueueSize(Ptr queue) // Check queue size every 1/100 of a second Simulator::Schedule(Seconds(0.001), &CheckQueueSize, queue); - std::ofstream fPlotQueue(std::stringstream(dir + "queue-size.dat").str(), - std::ios::out | std::ios::app); fPlotQueue << Simulator::Now().GetSeconds() << " " << qSize << std::endl; - fPlotQueue.close(); } // Function to trace change in cwnd at n0 static void CwndChange(uint32_t oldCwnd, uint32_t newCwnd) { - std::ofstream fPlotQueue(dir + "cwndTraces/n0.dat", std::ios::out | std::ios::app); - fPlotQueue << Simulator::Now().GetSeconds() << " " << newCwnd / segmentSize << std::endl; - fPlotQueue.close(); + fPlotCwnd << Simulator::Now().GetSeconds() << " " << newCwnd / segmentSize << std::endl; } // Function to calculate drops in a particular Queue @@ -228,15 +226,11 @@ main(int argc, char* argv[]) retVal = system(dirToRemove.c_str()); NS_ASSERT_MSG(retVal == 0, "Error in return value"); } - std::string dirToSave = "mkdir -p " + dir; - retVal = system(dirToSave.c_str()); - NS_ASSERT_MSG(retVal == 0, "Error in return value"); - retVal = system((dirToSave + "/pcap/").c_str()); - NS_ASSERT_MSG(retVal == 0, "Error in return value"); - retVal = system((dirToSave + "/queueTraces/").c_str()); - NS_ASSERT_MSG(retVal == 0, "Error in return value"); - retVal = system((dirToSave + "/cwndTraces/").c_str()); - NS_ASSERT_MSG(retVal == 0, "Error in return value"); + + SystemPath::MakeDirectories(dir); + SystemPath::MakeDirectories(dir + "/pcap/"); + SystemPath::MakeDirectories(dir + "/queueTraces/"); + SystemPath::MakeDirectories(dir + "/cwndTraces/"); // Set default parameters for queue discipline Config::SetDefault(qdiscTypeId + "::MaxSize", QueueSizeValue(QueueSize("100p"))); @@ -251,6 +245,10 @@ main(int argc, char* argv[]) // Enable BQL tch.SetQueueLimits("ns3::DynamicQueueLimits"); + // Open files for writing queue size and cwnd traces + fPlotQueue.open(dir + "queue-size.dat", std::ios::out); + fPlotCwnd.open(dir + "cwndTraces/n0.dat", std::ios::out); + // Calls function to check queue size Simulator::ScheduleNow(&CheckQueueSize, qd.Get(0)); @@ -299,5 +297,8 @@ main(int argc, char* argv[]) Simulator::Destroy(); + fPlotQueue.close(); + fPlotCwnd.close(); + return 0; }