如何获取NS-3中每个数据包的接收时间? (802.11n+MIMO 示例)

How to get the received time of each packet in NS-3? (802.11n+MIMO example)

我正在使用这个例子:https://github.com/nsnam/ns-3-dev-git/blob/master/examples/wireless/80211n-mimo.cc 我想获取要绘制的数据包的接收时间。我尝试使用 Simulator::Now().GetSeconds(); 但它每次都显示相同的值(6 秒) 请问还有什么办法可以解决吗

    /* Setting applications */
      ApplicationContainer serverApp;
      if (udp)
        {
          //UDP flow
          uint16_t port = 9;
          UdpServerHelper server (port);
          serverApp = server.Install (wifiStaNode.Get (0));
          serverApp.Start (Seconds (0.0));
          serverApp.Stop (Seconds (simulationTime + 1));

          UdpClientHelper client (staNodeInterface.GetAddress (0), port);
          client.SetAttribute ("MaxPackets", UintegerValue (4294967295u));
          client.SetAttribute ("Interval", TimeValue (Time ("0.00001"))); //packets/s
          client.SetAttribute ("PacketSize", UintegerValue (payloadSize));
          ApplicationContainer clientApp = client.Install (wifiApNode.Get (0));
          clientApp.Start (Seconds (1.0));
          clientApp.Stop (Seconds (simulationTime + 1));
        }
      else
        {
          //TCP flow
          uint16_t port = 50000;
          Address localAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
          PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", localAddress);
          serverApp = packetSinkHelper.Install (wifiStaNode.Get (0));
          serverApp.Start (Seconds (0.0));
          serverApp.Stop (Seconds (simulationTime + 1));

          OnOffHelper onoff ("ns3::TcpSocketFactory",Ipv4Address::GetAny ());
          onoff.SetAttribute ("OnTime",  StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
          onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
          onoff.SetAttribute ("PacketSize", UintegerValue (payloadSize));
          onoff.SetAttribute ("DataRate", DataRateValue (1000000000)); //bit/s
          AddressValue remoteAddress (InetSocketAddress (staNodeInterface.GetAddress (0), port));
          onoff.SetAttribute ("Remote", remoteAddress);
          ApplicationContainer clientApp = onoff.Install (wifiApNode.Get (0));
          clientApp.Start (Seconds (1.0));
          clientApp.Stop (Seconds (simulationTime + 1));
        }        

    Simulator::Stop (Seconds (simulationTime + 1));
      Simulator::Run ();

      double throughput = 0;

    **double received = Simulator::Now().GetSeconds();**

      if (udp)
        {
          //UDP
          uint64_t totalPacketsThrough = DynamicCast<UdpServer> (serverApp.Get (0))->GetReceived ();
          throughput = totalPacketsThrough * payloadSize * 8 / (simulationTime * 1000000.0); //Mbit/s
        }
      else
        {
          //TCP
          uint64_t totalPacketsThrough = DynamicCast<PacketSink> (serverApp.Get (0))->GetTotalRx ();
          throughput = totalPacketsThrough * 8 / (simulationTime * 1000000.0); //Mbit/s
        }
      dataset.Add (d, throughput);
      std::cout << throughput << " Mbit/s" << std::endl;

    **std::cout << "received After :" << received << " s" << std::endl;**

      d += step;
      Simulator::Destroy ();
    }
  plot.AddDataset (dataset);
}

我尝试使用 "Simulator::Now().GetSeconds();" 但它每次都显示相同的值(6 秒)。

Simulator::Now().GetSeconds() 返回相同的值,因为它是在模拟完成后调用的。必须在 实际模拟期间 调用它。一种方法是实际挖掘庞大的代码库(在本例中为 'src/internet/' 下的 TCP/UDP 模块)并找出哪个函数实际处理数据包的接收。但是为了让生活更轻松,ns-3 已经实现了 tracing 来处理这个问题。

要回答您的具体问题,您需要数据包接收器跟踪。

考虑在 main() 函数中安装数据包接收器的代码:

ApplicationContainer TcpSinkApps = TcpPacketSink.Install (nodeContainer.Get(0));
Ptr<PacketSink> pktSink = StaticCast<PacketSink> (TcpSinkApps.Get(0));
std::stringstream ss; ss << "Some information";
pktSink->TraceConnect("Rx", ss.str(), MakeCallback (&SinkRxTrace));

"Rx" 跟踪在packet-sink.cc 中定义,因此SinkRxTrace() 是每次成功接收数据包时都会调用的函数。现在您可以继续在代码中定义 SinkRxTrace()(当然在 main() 之上):

void SinkRxTrace(std::string context, Ptr<const Packet> pkt, const Address &addr)
{
  std::cout<<"Packet received at "<<Simulator::Now().GetSeconds()<<" s\n";
}