examples/tcp/tcp-variants-comparison.cc
changeset 10856 d45187afb01a
parent 10668 50137e334cf2
child 11156 be4bb6ee65d9
equal deleted inserted replaced
10855:7ef081ddfc7f 10856:d45187afb01a
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /*
     2 /*
     3  * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas 
     3  * Copyright (c) 2013 ResiliNets, ITTC, University of Kansas
     4  *
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     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
     6  * it under the terms of the GNU General Public License version 2 as
     7  * published by the Free Software Foundation;
     7  * published by the Free Software Foundation;
     8  *
     8  *
    52 
    52 
    53 using namespace ns3;
    53 using namespace ns3;
    54 
    54 
    55 NS_LOG_COMPONENT_DEFINE ("TcpVariantsComparison");
    55 NS_LOG_COMPONENT_DEFINE ("TcpVariantsComparison");
    56 
    56 
    57 double old_time = 0.0;
    57 bool firstCwnd = true;
    58 EventId output;
    58 bool firstSshThr = true;
    59 Time current = Time::FromInteger(3, Time::S);  //Only record cwnd and ssthresh values every 3 seconds
    59 Ptr<OutputStreamWrapper> cWndStream;
    60 bool first = true;
    60 Ptr<OutputStreamWrapper> ssThreshStream;
       
    61 uint32_t cWndValue;
       
    62 uint32_t ssThreshValue;
       
    63 
    61 
    64 
    62 static void
    65 static void
    63 OutputTrace ()
    66 CwndTracer (uint32_t oldval, uint32_t newval)
    64 {
    67 {
    65  // *stream->GetStream() << newtime << " " << newval << std::endl;
    68   if (firstCwnd)
    66  // old_time = newval;
    69     {
       
    70       *cWndStream->GetStream () << "0.0 " << oldval << std::endl;
       
    71       firstCwnd = false;
       
    72     }
       
    73   *cWndStream->GetStream () << Simulator::Now ().GetSeconds () << " " << newval << std::endl;
       
    74   cWndValue = newval;
       
    75 
       
    76   if (!firstSshThr)
       
    77     {
       
    78       *ssThreshStream->GetStream () << Simulator::Now ().GetSeconds () << " " << ssThreshValue << std::endl;
       
    79     }
    67 }
    80 }
    68 
    81 
    69 static void
    82 static void
    70 CwndTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
    83 SsThreshTracer (uint32_t oldval, uint32_t newval)
    71 {
    84 {
    72   double new_time = Simulator::Now().GetSeconds();
    85   if (firstSshThr)
    73   if (old_time == 0 && first)
    86     {
    74   {
    87       *ssThreshStream->GetStream () << "0.0 " << oldval << std::endl;
    75     double mycurrent = current.GetSeconds();
    88       firstSshThr = false;
    76     *stream->GetStream() << new_time << " " << mycurrent << " " << newval << std::endl;
    89     }
    77     first = false;
    90   *ssThreshStream->GetStream () << Simulator::Now ().GetSeconds () << " " << newval << std::endl;
    78     output = Simulator::Schedule(current,&OutputTrace);
    91   ssThreshValue = newval;
    79   }
    92 
    80   else
    93   if (!firstCwnd)
    81   {
    94     {
    82     if (output.IsExpired())
    95       *cWndStream->GetStream () << Simulator::Now ().GetSeconds () << " " << cWndValue << std::endl;
    83     {
    96     }
    84       *stream->GetStream() << new_time << " " << newval << std::endl;
    97 }
    85       output.Cancel();
    98 
    86       output = Simulator::Schedule(current,&OutputTrace);
       
    87     }
       
    88   }
       
    89 }
       
    90 
       
    91 static void
       
    92 SsThreshTracer (Ptr<OutputStreamWrapper>stream, uint32_t oldval, uint32_t newval)
       
    93 {
       
    94   double new_time = Simulator::Now().GetSeconds();
       
    95   if (old_time == 0 && first)
       
    96   {
       
    97     double mycurrent = current.GetSeconds();
       
    98     *stream->GetStream() << new_time << " " << mycurrent << " " << newval << std::endl;
       
    99     first = false;
       
   100     output = Simulator::Schedule(current,&OutputTrace);
       
   101   }
       
   102   else
       
   103   {
       
   104     if (output.IsExpired())
       
   105     {
       
   106       *stream->GetStream() << new_time << " " << newval << std::endl;
       
   107       output.Cancel();
       
   108       output = Simulator::Schedule(current,&OutputTrace);
       
   109     }
       
   110   }
       
   111 }
       
   112 
    99 
   113 static void
   100 static void
   114 TraceCwnd (std::string cwnd_tr_file_name)
   101 TraceCwnd (std::string cwnd_tr_file_name)
   115 {
   102 {
   116   AsciiTraceHelper ascii;
   103   AsciiTraceHelper ascii;
   117   if (cwnd_tr_file_name.compare("") == 0)
   104   cWndStream = ascii.CreateFileStream (cwnd_tr_file_name.c_str ());
   118      {
   105   Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));
   119        NS_LOG_DEBUG ("No trace file for cwnd provided");
       
   120        return;
       
   121      }
       
   122   else
       
   123     {
       
   124       Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream(cwnd_tr_file_name.c_str());
       
   125       Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",MakeBoundCallback (&CwndTracer, stream));
       
   126     }
       
   127 }
   106 }
   128 
   107 
   129 static void
   108 static void
   130 TraceSsThresh(std::string ssthresh_tr_file_name)
   109 TraceSsThresh (std::string ssthresh_tr_file_name)
   131 {
   110 {
   132   AsciiTraceHelper ascii;
   111   AsciiTraceHelper ascii;
   133   if (ssthresh_tr_file_name.compare("") == 0)
   112   ssThreshStream = ascii.CreateFileStream (ssthresh_tr_file_name.c_str ());
   134     {
   113   Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/SlowStartThreshold",MakeCallback (&SsThreshTracer));
   135       NS_LOG_DEBUG ("No trace file for ssthresh provided");
       
   136       return;
       
   137     }
       
   138   else
       
   139     {
       
   140       Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream(ssthresh_tr_file_name.c_str());
       
   141       Config::ConnectWithoutContext ("/NodeList/1/$ns3::TcpL4Protocol/SocketList/0/SlowStartThreshold",MakeBoundCallback (&SsThreshTracer, stream));
       
   142     }
       
   143 }
   114 }
   144 
   115 
   145 int main (int argc, char *argv[])
   116 int main (int argc, char *argv[])
   146 {
   117 {
   147   std::string transport_prot = "TcpWestwood";
   118   std::string transport_prot = "TcpWestwood";
   160   uint32_t run = 0;
   131   uint32_t run = 0;
   161   bool flow_monitor = true;
   132   bool flow_monitor = true;
   162 
   133 
   163 
   134 
   164   CommandLine cmd;
   135   CommandLine cmd;
   165   cmd.AddValue("transport_prot", "Transport protocol to use: TcpTahoe, TcpReno, TcpNewReno, TcpWestwood, TcpWestwoodPlus ", transport_prot);
   136   cmd.AddValue ("transport_prot", "Transport protocol to use: TcpTahoe, TcpReno, TcpNewReno, TcpWestwood, TcpWestwoodPlus ", transport_prot);
   166   cmd.AddValue("error_p", "Packet error rate", error_p);
   137   cmd.AddValue ("error_p", "Packet error rate", error_p);
   167   cmd.AddValue("bandwidth", "Bottleneck bandwidth", bandwidth);
   138   cmd.AddValue ("bandwidth", "Bottleneck bandwidth", bandwidth);
   168   cmd.AddValue("access_bandwidth", "Access link bandwidth", access_bandwidth);
   139   cmd.AddValue ("access_bandwidth", "Access link bandwidth", access_bandwidth);
   169   cmd.AddValue("delay", "Access link delay", access_delay);
   140   cmd.AddValue ("delay", "Access link delay", access_delay);
   170   cmd.AddValue("tracing", "Flag to enable/disable tracing", tracing);
   141   cmd.AddValue ("tracing", "Flag to enable/disable tracing", tracing);
   171   cmd.AddValue("tr_name", "Name of output trace file", tr_file_name);
   142   cmd.AddValue ("tr_name", "Name of output trace file", tr_file_name);
   172   cmd.AddValue("cwnd_tr_name", "Name of output trace file", cwnd_tr_file_name);
   143   cmd.AddValue ("cwnd_tr_name", "Name of output trace file", cwnd_tr_file_name);
   173   cmd.AddValue("ssthresh_tr_name", "Name of output trace file", ssthresh_tr_file_name);
   144   cmd.AddValue ("ssthresh_tr_name", "Name of output trace file", ssthresh_tr_file_name);
   174   cmd.AddValue("data", "Number of Megabytes of data to transmit", data_mbytes);
   145   cmd.AddValue ("data", "Number of Megabytes of data to transmit", data_mbytes);
   175   cmd.AddValue("mtu", "Size of IP packets to send in bytes", mtu_bytes);
   146   cmd.AddValue ("mtu", "Size of IP packets to send in bytes", mtu_bytes);
   176   cmd.AddValue("num_flows", "Number of flows", num_flows);
   147   cmd.AddValue ("num_flows", "Number of flows", num_flows);
   177   cmd.AddValue("duration", "Time to allow flows to run in seconds", duration);
   148   cmd.AddValue ("duration", "Time to allow flows to run in seconds", duration);
   178   cmd.AddValue("run", "Run index (for setting repeatable seeds)", run);
   149   cmd.AddValue ("run", "Run index (for setting repeatable seeds)", run);
   179   cmd.AddValue("flow_monitor", "Enable flow monitor", flow_monitor);
   150   cmd.AddValue ("flow_monitor", "Enable flow monitor", flow_monitor);
   180   cmd.Parse (argc, argv);
   151   cmd.Parse (argc, argv);
   181 
   152 
   182   SeedManager::SetSeed(1);
   153   SeedManager::SetSeed (1);
   183   SeedManager::SetRun(run);
   154   SeedManager::SetRun (run);
   184 
   155 
   185   // User may find it convenient to enable logging
   156   // User may find it convenient to enable logging
   186   //LogComponentEnable("TcpVariantsComparison", LOG_LEVEL_ALL);
   157   //LogComponentEnable("TcpVariantsComparison", LOG_LEVEL_ALL);
   187   //LogComponentEnable("BulkSendApplication", LOG_LEVEL_INFO);
   158   //LogComponentEnable("BulkSendApplication", LOG_LEVEL_INFO);
   188   //LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
   159   //LogComponentEnable("DropTailQueue", LOG_LEVEL_ALL);
   189 
   160 
   190   // Calculate the ADU size
   161   // Calculate the ADU size
   191   Header* temp_header = new Ipv4Header();
   162   Header* temp_header = new Ipv4Header ();
   192   uint32_t ip_header = temp_header->GetSerializedSize();
   163   uint32_t ip_header = temp_header->GetSerializedSize ();
   193   NS_LOG_LOGIC ("IP Header size is: " << ip_header);
   164   NS_LOG_LOGIC ("IP Header size is: " << ip_header);
   194   delete temp_header;
   165   delete temp_header;
   195   temp_header = new TcpHeader();
   166   temp_header = new TcpHeader ();
   196   uint32_t tcp_header = temp_header->GetSerializedSize();
   167   uint32_t tcp_header = temp_header->GetSerializedSize ();
   197   NS_LOG_LOGIC ("TCP Header size is: " << tcp_header);
   168   NS_LOG_LOGIC ("TCP Header size is: " << tcp_header);
   198   delete temp_header;
   169   delete temp_header;
   199   uint32_t tcp_adu_size = mtu_bytes - (ip_header + tcp_header);
   170   uint32_t tcp_adu_size = mtu_bytes - (ip_header + tcp_header);
   200   NS_LOG_LOGIC ("TCP ADU size is: " << tcp_adu_size);
   171   NS_LOG_LOGIC ("TCP ADU size is: " << tcp_adu_size);
   201 
   172 
   202   // Set the simulation start and stop time
   173   // Set the simulation start and stop time
   203   float start_time = 0.1;
   174   float start_time = 0.1;
   204   float stop_time = start_time + duration;
   175   float stop_time = start_time + duration;
   205 
   176 
   206   // Select TCP variant
   177   // Select TCP variant
   207   if (transport_prot.compare("TcpTahoe") == 0)
   178   if (transport_prot.compare ("TcpTahoe") == 0)
   208     Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpTahoe::GetTypeId()));
   179     {
   209   else if (transport_prot.compare("TcpReno") == 0)
   180       Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpTahoe::GetTypeId ()));
   210     Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpReno::GetTypeId()));
   181     }
   211   else if (transport_prot.compare("TcpNewReno") == 0)
   182   else if (transport_prot.compare ("TcpReno") == 0)
   212     Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpNewReno::GetTypeId()));
   183     {
   213   else if (transport_prot.compare("TcpWestwood") == 0)
   184       Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpReno::GetTypeId ()));
   214     {// the default protocol type in ns3::TcpWestwood is WESTWOOD
   185     }
   215       Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId()));
   186   else if (transport_prot.compare ("TcpNewReno") == 0)
   216       Config::SetDefault("ns3::TcpWestwood::FilterType", EnumValue(TcpWestwood::TUSTIN));
   187     {
   217     }
   188       Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpNewReno::GetTypeId ()));
   218   else if (transport_prot.compare("TcpWestwoodPlus") == 0)
   189     }
   219     {
   190   else if (transport_prot.compare ("TcpWestwood") == 0)
   220       Config::SetDefault("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId()));
   191     { // the default protocol type in ns3::TcpWestwood is WESTWOOD
   221       Config::SetDefault("ns3::TcpWestwood::ProtocolType", EnumValue(TcpWestwood::WESTWOODPLUS));
   192       Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));
   222       Config::SetDefault("ns3::TcpWestwood::FilterType", EnumValue(TcpWestwood::TUSTIN));
   193       Config::SetDefault ("ns3::TcpWestwood::FilterType", EnumValue (TcpWestwood::TUSTIN));
       
   194     }
       
   195   else if (transport_prot.compare ("TcpWestwoodPlus") == 0)
       
   196     {
       
   197       Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));
       
   198       Config::SetDefault ("ns3::TcpWestwood::ProtocolType", EnumValue (TcpWestwood::WESTWOODPLUS));
       
   199       Config::SetDefault ("ns3::TcpWestwood::FilterType", EnumValue (TcpWestwood::TUSTIN));
   223     }
   200     }
   224   else
   201   else
   225     {
   202     {
   226       NS_LOG_DEBUG ("Invalid TCP version");
   203       NS_LOG_DEBUG ("Invalid TCP version");
   227       exit (1);
   204       exit (1);
   229 
   206 
   230   // Create gateways, sources, and sinks
   207   // Create gateways, sources, and sinks
   231   NodeContainer gateways;
   208   NodeContainer gateways;
   232   gateways.Create (1);
   209   gateways.Create (1);
   233   NodeContainer sources;
   210   NodeContainer sources;
   234   sources.Create(num_flows);
   211   sources.Create (num_flows);
   235   NodeContainer sinks;
   212   NodeContainer sinks;
   236   sinks.Create(num_flows);
   213   sinks.Create (num_flows);
   237 
   214 
   238   // Configure the error model
   215   // Configure the error model
   239   // Here we use RateErrorModel with packet error rate
   216   // Here we use RateErrorModel with packet error rate
   240   Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable>();
   217   Ptr<UniformRandomVariable> uv = CreateObject<UniformRandomVariable> ();
   241   uv->SetStream (50);
   218   uv->SetStream (50);
   242   RateErrorModel error_model;
   219   RateErrorModel error_model;
   243   error_model.SetRandomVariable(uv);
   220   error_model.SetRandomVariable (uv);
   244   error_model.SetUnit(RateErrorModel::ERROR_UNIT_PACKET);
   221   error_model.SetUnit (RateErrorModel::ERROR_UNIT_PACKET);
   245   error_model.SetRate(error_p);
   222   error_model.SetRate (error_p);
   246 
   223 
   247   PointToPointHelper UnReLink;
   224   PointToPointHelper UnReLink;
   248   UnReLink.SetDeviceAttribute ("DataRate", StringValue (bandwidth));
   225   UnReLink.SetDeviceAttribute ("DataRate", StringValue (bandwidth));
   249   UnReLink.SetChannelAttribute ("Delay", StringValue ("0.01ms"));
   226   UnReLink.SetChannelAttribute ("Delay", StringValue ("0.01ms"));
   250   UnReLink.SetDeviceAttribute ("ReceiveErrorModel", PointerValue (&error_model));
   227   UnReLink.SetDeviceAttribute ("ReceiveErrorModel", PointerValue (&error_model));
   260   // and the channels between the sources/sinks and the gateways
   237   // and the channels between the sources/sinks and the gateways
   261   PointToPointHelper LocalLink;
   238   PointToPointHelper LocalLink;
   262   LocalLink.SetDeviceAttribute ("DataRate", StringValue (access_bandwidth));
   239   LocalLink.SetDeviceAttribute ("DataRate", StringValue (access_bandwidth));
   263   LocalLink.SetChannelAttribute ("Delay", StringValue (access_delay));
   240   LocalLink.SetChannelAttribute ("Delay", StringValue (access_delay));
   264   Ipv4InterfaceContainer sink_interfaces;
   241   Ipv4InterfaceContainer sink_interfaces;
   265   for (int i=0; i<num_flows; i++)
   242   for (int i = 0; i < num_flows; i++)
   266     {
   243     {
   267       NetDeviceContainer devices;
   244       NetDeviceContainer devices;
   268       devices = LocalLink.Install(sources.Get(i), gateways.Get(0));
   245       devices = LocalLink.Install (sources.Get (i), gateways.Get (0));
   269       address.NewNetwork();
   246       address.NewNetwork ();
   270       Ipv4InterfaceContainer interfaces = address.Assign (devices);
   247       Ipv4InterfaceContainer interfaces = address.Assign (devices);
   271       devices = UnReLink.Install(gateways.Get(0), sinks.Get(i));
   248       devices = UnReLink.Install (gateways.Get (0), sinks.Get (i));
   272       address.NewNetwork();
   249       address.NewNetwork ();
   273       interfaces = address.Assign (devices);
   250       interfaces = address.Assign (devices);
   274       sink_interfaces.Add(interfaces.Get(1));
   251       sink_interfaces.Add (interfaces.Get (1));
   275     }
   252     }
   276 
   253 
   277   NS_LOG_INFO ("Initialize Global Routing.");
   254   NS_LOG_INFO ("Initialize Global Routing.");
   278   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
   255   Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
   279 
   256 
   280   uint16_t port = 50000;
   257   uint16_t port = 50000;
   281   Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
   258   Address sinkLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
   282   PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
   259   PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", sinkLocalAddress);
   283 
   260 
   284   for(uint16_t i=0; i<sources.GetN(); i++)
   261   for (uint16_t i = 0; i < sources.GetN (); i++)
   285     {
   262     {
   286       AddressValue remoteAddress (InetSocketAddress (sink_interfaces.GetAddress(i, 0), port));
   263       AddressValue remoteAddress (InetSocketAddress (sink_interfaces.GetAddress (i, 0), port));
   287 
   264 
   288       if (transport_prot.compare("TcpTahoe") == 0
   265       if (transport_prot.compare ("TcpTahoe") == 0
   289           || transport_prot.compare("TcpReno") == 0
   266           || transport_prot.compare ("TcpReno") == 0
   290           || transport_prot.compare("TcpNewReno") == 0
   267           || transport_prot.compare ("TcpNewReno") == 0
   291           || transport_prot.compare("TcpWestwood") == 0
   268           || transport_prot.compare ("TcpWestwood") == 0
   292           || transport_prot.compare("TcpWestwoodPlus") == 0)
   269           || transport_prot.compare ("TcpWestwoodPlus") == 0)
   293         {
   270         {
   294           Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (tcp_adu_size));
   271           Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (tcp_adu_size));
   295           BulkSendHelper ftp("ns3::TcpSocketFactory", Address());
   272           BulkSendHelper ftp ("ns3::TcpSocketFactory", Address ());
   296           ftp.SetAttribute ("Remote", remoteAddress);
   273           ftp.SetAttribute ("Remote", remoteAddress);
   297           ftp.SetAttribute ("SendSize", UintegerValue (tcp_adu_size));
   274           ftp.SetAttribute ("SendSize", UintegerValue (tcp_adu_size));
   298           ftp.SetAttribute ("MaxBytes", UintegerValue (int(data_mbytes*1000000)));
   275           ftp.SetAttribute ("MaxBytes", UintegerValue (int(data_mbytes * 1000000)));
   299 
   276 
   300           ApplicationContainer sourceApp = ftp.Install (sources.Get(i));
   277           ApplicationContainer sourceApp = ftp.Install (sources.Get (i));
   301           sourceApp.Start (Seconds (start_time*i));
   278           sourceApp.Start (Seconds (start_time * i));
   302           sourceApp.Stop (Seconds (stop_time - 3));
   279           sourceApp.Stop (Seconds (stop_time - 3));
   303 
   280 
   304           sinkHelper.SetAttribute ("Protocol", TypeIdValue (TcpSocketFactory::GetTypeId ()));
   281           sinkHelper.SetAttribute ("Protocol", TypeIdValue (TcpSocketFactory::GetTypeId ()));
   305           ApplicationContainer sinkApp = sinkHelper.Install (sinks);
   282           ApplicationContainer sinkApp = sinkHelper.Install (sinks);
   306           sinkApp.Start (Seconds (start_time*i));
   283           sinkApp.Start (Seconds (start_time * i));
   307           sinkApp.Stop (Seconds (stop_time));
   284           sinkApp.Stop (Seconds (stop_time));
   308         }
   285         }
   309       else
   286       else
   310         {
   287         {
   311           NS_LOG_DEBUG ("Invalid transport protocol " << transport_prot << " specified");
   288           NS_LOG_DEBUG ("Invalid transport protocol " << transport_prot << " specified");
   314     }
   291     }
   315 
   292 
   316   // Set up tracing if enabled
   293   // Set up tracing if enabled
   317   if (tracing)
   294   if (tracing)
   318     {
   295     {
   319       std::ofstream ascii;
   296       if (tr_file_name.compare ("") != 0)
   320       Ptr<OutputStreamWrapper> ascii_wrap;
   297         {
   321       if (tr_file_name.compare("") == 0)
   298           std::ofstream ascii;
   322         {
   299           Ptr<OutputStreamWrapper> ascii_wrap;
   323           NS_LOG_DEBUG ("No trace file provided");
   300           ascii.open (tr_file_name.c_str ());
   324           exit (1);
   301           ascii_wrap = new OutputStreamWrapper (tr_file_name.c_str (), std::ios::out);
   325         }
   302           stack.EnableAsciiIpv4All (ascii_wrap);
   326       else
   303         }
   327         {
   304 
   328           ascii.open (tr_file_name.c_str());
   305       if (cwnd_tr_file_name.compare ("") != 0)
   329           ascii_wrap = new OutputStreamWrapper(tr_file_name.c_str(), std::ios::out);
   306         {
   330         }
   307           Simulator::Schedule (Seconds (0.00001), &TraceCwnd, cwnd_tr_file_name);
   331 
   308         }
   332       stack.EnableAsciiIpv4All (ascii_wrap);
   309 
   333 
   310       if (ssthresh_tr_file_name.compare ("") != 0)
   334       Simulator::Schedule(Seconds(0.00001), &TraceCwnd, cwnd_tr_file_name);
   311         {
   335       Simulator::Schedule(Seconds(0.00001), &TraceSsThresh, ssthresh_tr_file_name);
   312           Simulator::Schedule (Seconds (0.00001), &TraceSsThresh, ssthresh_tr_file_name);
   336     }
   313         }
   337 
   314 
   338   UnReLink.EnablePcapAll("TcpVariantsComparison", true);
   315     }
   339   LocalLink.EnablePcapAll("TcpVariantsComparison", true);
   316 
       
   317   UnReLink.EnablePcapAll ("TcpVariantsComparison", true);
       
   318   LocalLink.EnablePcapAll ("TcpVariantsComparison", true);
   340 
   319 
   341   // Flow monitor
   320   // Flow monitor
   342   FlowMonitorHelper flowHelper;
   321   FlowMonitorHelper flowHelper;
   343   if (flow_monitor)
   322   if (flow_monitor)
   344     {
   323     {
   345       flowHelper.InstallAll();
   324       flowHelper.InstallAll ();
   346     }
   325     }
   347 
   326 
   348   Simulator::Stop (Seconds(stop_time));
   327   Simulator::Stop (Seconds (stop_time));
   349   Simulator::Run ();
   328   Simulator::Run ();
   350 
   329 
   351   if (flow_monitor)
   330   if (flow_monitor)
   352     {
   331     {
   353       flowHelper.SerializeToXmlFile("TcpVariantsComparison.flowmonitor", true, true);
   332       flowHelper.SerializeToXmlFile ("TcpVariantsComparison.flowmonitor", true, true);
   354     }
   333     }
   355 
   334 
   356   Simulator::Destroy ();
   335   Simulator::Destroy ();
   357   return 0;
   336   return 0;
   358 }
   337 }