如何获取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";
}
我正在使用这个例子: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";
}