为什么FlowMonitor不收集ns3中dsr.cc的数据?

时间:2018-08-11 13:28:18

标签: c++ network-programming ns-3

我已经测试了FlowMonitor的某些程序,并且可以正常工作。但是对于ns3示例中可用的dsr,它不会收集任何数据。我错过了什么?

这是程序, 使用Fedora 28,GCC 8,ns-3.28

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/mobility-module.h"
#include "ns3/config-store-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/dsr-module.h"
#include "ns3/netanim-module.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/flow-monitor-module.h"

#include <sstream>

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("DsrTest");

int
main (int argc, char *argv[])
{
  //
  // Users may find it convenient to turn on explicit debugging
  // for selected modules; the below lines suggest how to do this
  //
#if 0
  LogComponentEnable ("Ipv4L3Protocol", LOG_LEVEL_ALL);
  LogComponentEnable ("UdpL4Protocol", LOG_LEVEL_ALL);
  LogComponentEnable ("UdpSocketImpl", LOG_LEVEL_ALL);
  LogComponentEnable ("NetDevice", LOG_LEVEL_ALL);
  LogComponentEnable ("Ipv4EndPointDemux", LOG_LEVEL_ALL);
#endif

#if 0
  LogComponentEnable ("DsrOptions", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrHelper", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRouting", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrOptionHeader", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrFsHeader", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrGraReplyTable", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrSendBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRouteCache", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrMaintainBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrRreqTable", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrErrorBuffer", LOG_LEVEL_ALL);
  LogComponentEnable ("DsrNetworkQueue", LOG_LEVEL_ALL);
#endif

  NS_LOG_INFO ("creating the nodes");

  // General parameters 
  uint32_t nWifis = 50;
  uint32_t nSinks = 10;
  double TotalTime = 600.0;
  double dataTime = 500.0;
  double ppers = 1;
  uint32_t packetSize = 64;
  double dataStart = 1.0; // start sending data at 100s


  //mobility parameters
  double pauseTime = 0.0;
  double nodeSpeed = 20.0;
  double txpDistance = 250.0;
  std::string outputFileName = "Results/DSR/dsr_final_results_"+(std::to_string(nWifis));//+"-nWifis"+(std::to_string(nodeSpeed))+"-nodeSpeed_"+(std::to_string(nSinks))+"-nSinks_"+(std::to_string(txpDistance))+"-txpDistance";

  std::string rate = "0.512kbps";
  std::string dataMode ("DsssRate11Mbps");
  std::string phyMode ("DsssRate11Mbps");

  //Allow users to override the default parameters and set it to new ones from CommandLine.
  CommandLine cmd;
  cmd.AddValue ("nWifis", "Number of wifi nodes", nWifis);
  cmd.AddValue ("nSinks", "Number of SINK traffic nodes", nSinks);
  cmd.AddValue ("rate", "CBR traffic rate(in kbps), Default:8", rate);
  cmd.AddValue ("nodeSpeed", "Node speed in RandomWayPoint model, Default:20", nodeSpeed);
  cmd.AddValue ("packetSize", "The packet size", packetSize);
  cmd.AddValue ("txpDistance", "Specify node's transmit range, Default:300", txpDistance);
  cmd.AddValue ("pauseTime", "pauseTime for mobility model, Default: 0", pauseTime);
  cmd.Parse (argc, argv);

  SeedManager::SetSeed (10);
  SeedManager::SetRun (1);

  NodeContainer adhocNodes;
  adhocNodes.Create (nWifis);
  NetDeviceContainer allDevices;

  NS_LOG_INFO ("setting the default phy and channel parameters");
  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode", StringValue (phyMode));
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
  // disable fragmentation for frames below 2200 bytes
  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2200"));

  NS_LOG_INFO ("setting the default phy and channel parameters ");
  WifiHelper wifi;
  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);
  YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();

  YansWifiChannelHelper wifiChannel;
  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
  wifiChannel.AddPropagationLoss ("ns3::RangePropagationLossModel", "MaxRange", DoubleValue (txpDistance));
  wifiPhy.SetChannel (wifiChannel.Create ());

  // Add a mac and disable rate control
  WifiMacHelper wifiMac;
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager", "DataMode", StringValue (dataMode), "ControlMode",
                                StringValue (phyMode));

  wifiMac.SetType ("ns3::AdhocWifiMac");
  allDevices = wifi.Install (wifiPhy, wifiMac, adhocNodes);

  NS_LOG_INFO ("Configure Tracing.");

  AsciiTraceHelper ascii;
  Ptr<OutputStreamWrapper> stream = ascii.CreateFileStream (outputFileName+".tr");
  wifiPhy.EnableAsciiAll (stream);
  wifiPhy.EnablePcapAll(outputFileName);

  //read the SUMO generated trace file
  //Ns2MobilityHelper adhocMobility = Ns2MobilityHelper ("scratch/trace_files/dsr/dsr_final_"+(std::to_string(nWifis))+".tcl");
  Ns2MobilityHelper adhocMobility = Ns2MobilityHelper ("scratch/dsr_final_50.tcl");

  adhocMobility.Install();

  InternetStackHelper internet;
  DsrMainHelper dsrMain;
  DsrHelper dsr;
  internet.Install (adhocNodes);
  dsrMain.Install (dsr, adhocNodes);

  NS_LOG_INFO ("assigning ip address");
  Ipv4AddressHelper address;
  address.SetBase ("10.1.1.0", "255.255.255.0");
  Ipv4InterfaceContainer allInterfaces;
  allInterfaces = address.Assign (allDevices);

  uint16_t port = 9;
  double randomStartTime = (1 / ppers) / nSinks; //distributed btw 1s evenly as we are sending 4pkt/s

  for (uint32_t i = 0; i < nSinks; ++i)
    {
      PacketSinkHelper sink ("ns3::UdpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
      ApplicationContainer apps_sink = sink.Install (adhocNodes.Get (i));
      apps_sink.Start (Seconds (0.0));
      apps_sink.Stop (Seconds (TotalTime));

      OnOffHelper onoff1 ("ns3::UdpSocketFactory", Address (InetSocketAddress (allInterfaces.GetAddress (i), port)));
      onoff1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"));
      onoff1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0]"));
      onoff1.SetAttribute ("PacketSize", UintegerValue (packetSize));
      onoff1.SetAttribute ("DataRate", DataRateValue (DataRate (rate)));

      ApplicationContainer apps1 = onoff1.Install (adhocNodes.Get (i + nWifis - nSinks));
      apps1.Start (Seconds (dataStart + i * randomStartTime));
      apps1.Stop (Seconds (dataTime + i * randomStartTime));
    }

    Ptr<FlowMonitor> flowmon;
    FlowMonitorHelper flowmonHelper;
    flowmon = flowmonHelper.InstallAll ();


    NS_LOG_INFO ("Run Simulation.");

  Simulator::Stop (Seconds (TotalTime));

  AnimationInterface anim (outputFileName+"_anim.xml");
  anim.SetMaxPktsPerTraceFile(99999999999);

  Simulator::Run ();
  flowmon->CheckForLostPackets (); 
  Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmonHelper.GetClassifier ());
  std::map<FlowId, FlowMonitor::FlowStats> stats = flowmon->GetFlowStats ();

for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator iter = stats.begin (); iter != stats.end (); ++iter)
  {
  Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (iter->first);

      NS_LOG_UNCOND("Flow ID: " << iter->first << " Src Addr " << t.sourceAddress << " Dst Addr " << t.destinationAddress);
          NS_LOG_UNCOND("Tx Packets = " << iter->second.txPackets);
          NS_LOG_UNCOND("Rx Packets = " << iter->second.rxPackets);
          NS_LOG_UNCOND("Throughput: " << iter->second.rxBytes * 8.0 / (iter->second.timeLastRxPacket.GetSeconds()-iter->second.timeFirstTxPacket.GetSeconds()) / 1024  << " Kbps");
  }
  flowmon->SerializeToXmlFile (outputFileName+"_flow.xml", true, true);


  Simulator::Destroy ();
}

1 个答案:

答案 0 :(得分:0)

这是由于DSR的实现方式所致。 请参阅the Bug 1844

中的讨论
  

DSR是IP级别的路由协议。 FlowMonitor不跟踪它   原因有两个:1)FlowMonitor不跟踪多播数据包(和DSR   使用广播地址),以及2)DSR数据包不是UDP或TCP   (FlowMonitor仅跟踪L4协议。)

     

因此,空报告几乎是正常的。

     

我将以“无效”关闭此错误。

     

如果您愿意,我们可以打开另一个错误(增强级别)来跟踪该错误   跟踪多播和IP级别的流量(也许   根据协议对其进行划分)。

     

困难可能是找到适合那种统计数据   流量,因为一些实际跟踪到的流量几乎没有   多播/广播消息完全没有意义。

  

Dsr是UDP / TCP和IP之间的 shim 协议。其实呢   将L4流量封装在自己的数据包中。或者,如果您更喜欢   这个想法,就是在IP和UDP / TCP之间添加了标头。

     

FlowMonitor无法理解这一点,并且数据包也无法   跟踪。就这么简单。

     

解决此问题的方法是在UDP / TCP级别标记数据包,然后   而不是IP级别,这比人们想象的要复杂一些。

     

另一方面,我们可以使用实际的标签系统来完成此操作,但我会   必须考虑一下。