Расчет пропускной способности NS3
В настоящее время я пытаюсь использовать сетевой симулятор NS3 для выполнения тестов одной стационарной точки доступа, передающей данные на мобильный узел (используя 802.11a, TCP).
Кажется, что код прекрасно компилируется, и ранее он выводил корректно выглядящие данные, поэтому я мог построить график производительности движущегося узла в зависимости от его расстояния до точки доступа, а затем узнать, как меняется схема модуляции точки доступа в зависимости от расстояния до мобильного узла.
Я внес небольшое изменение в метод ThroughputPerSecond, и теперь симуляция застряла в бесконечном цикле (он не останавливается через 240 секунд) и выводит только все нули. Я так расстроен, увидев код, пытающийся внести изменения в мелочи за последние 6 часов, и подумал, может, кто-то более опытный, чем я, мог бы взглянуть на это и посмотреть, есть ли что-то явно очевидное, что я пропускаю?
Я приложил весь свой код, но я думаю, что проблема заключается только в том маленьком методе ThroughputPerSecond, хотя я не могу понять, где.
Буду признателен за любую оказанную помощь.
#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/athstats-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include <iostream>
using namespace ns3;
static bool g_verbose = true;
void
PhyTxTrace (std::string context, Ptr<const Packet> packet, WifiMode mode, WifiPreamble preamble, uint8_t txPower)
{
if (g_verbose)
{
// Output the data rates for each data packet received
std::cout << "PHYTX mode=" << mode << " " << *packet << std::endl;
}
}
static void
SetPosition (Ptr<Node> node, Vector position)
{
// Set node's initial position
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
mobility->SetPosition (position);
}
static Vector
GetPosition (Ptr<Node> node)
{
// get node's current position
Ptr<MobilityModel> mobility = node->GetObject<MobilityModel> ();
return mobility->GetPosition ();
}
static void
AdvancePosition (Ptr<Node> node)
{
// advance node's position
Vector pos = GetPosition (node);
pos.x += 1.0;
if (pos.x >= 120.0){
return;
}
SetPosition (node, pos);
if (g_verbose){
//std::cout << "x="<<pos.x << std::endl;
}
// Reschedule AdvancePosition
Simulator::Schedule (Seconds (0.1), &AdvancePosition, node);
}
void
ThroughputPerSecond (Ptr<Application> sink1Apps, int totalPacketsThrough, Ptr<Node> node)
{
double throughput = 0.0;
Ptr<PacketSink> sink1 = DynamicCast<PacketSink> (sink1Apps);
// Calculate and output throughput per second
totalPacketsThrough = sink1->GetTotalRx ();
throughput = totalPacketsThrough*8/((237.0)*1000000.0);
std::cout << throughput;
// Reschedule ThroughputPerSecond
//
Simulator::Schedule (Seconds (0.0), &ThroughputPerSecond, sink1Apps, totalPacketsThrough, node);
}
int main (int argc, char *argv[])
{
Packet::EnablePrinting();
CommandLine cmd;
cmd.AddValue ("verbose", "Print trace information if true", g_verbose);
cmd.Parse (argc, argv);
// disable RTS/CTS.
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("99999999"));
// disable fragmentation
Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("2222200"));
WifiHelper wifi = WifiHelper::Default ();
MobilityHelper mobility;
NodeContainer stas;
NodeContainer ap;
NetDeviceContainer staDevs,apDevs;
Time interPacketInterval;
// Create 1 node, playing the role of the mobile node and 1 node, playing the role of the AP
stas.Create(1);
ap.Create(1);
// Create and setup the wifi Channel, wifi physical and MAC layers for the nodes
wifi.SetStandard(WIFI_PHY_STANDARD_80211a);
interPacketInterval = Seconds (0.00015); //802.11a & 802.11g speeds
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
Ssid ssid = Ssid ("wifi-default");
// setup the mobile node and the AP (install net devices)
wifiMac.SetType ("ns3::StaWifiMac", "Ssid", SsidValue (ssid), "ActiveProbing", BooleanValue (false));
staDevs = wifi.Install(wifiPhy, wifiMac, stas);
wifiMac.SetType ("ns3::ApWifiMac", "Ssid", SsidValue (ssid));
apDevs = wifi.Install(wifiPhy, wifiMac, ap);
// Setup the mobility model for the mobile node and the AP
mobility.Install (ap);
mobility.Install (stas);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
// Set initial positions of both nodes
SetPosition (ap.Get(0), Vector (0.0, 0.0, 0.0));
SetPosition (stas.Get(0), Vector (-120.0, -20.0, 0.0));
// Start moving the mobile node at Second 0.5 by calling AdvancePostion function
Simulator::Schedule (Seconds (0.5), &AdvancePosition, stas.Get(0));
// Add the Internet Stack and assign IPs for the mobile node and AP
InternetStackHelper internet;
internet.Install (ap);
internet.Install (stas);
Ipv4AddressHelper address;
address.SetBase("10.1.3.0", "255.255.255.0");
Ipv4InterfaceContainer apConnection = address.Assign(apDevs);
Ipv4InterfaceContainer staConnection = address.Assign(staDevs);
//Ipv4Address serverAddress = Ipv4Address(apConnection.GetAddress(0,0));
//
// Create application pairs for TCP or UDP using information in the spec
// setting AP as the data source and the mobile node as the receiver of this data
//
uint16_t port = 9; //Typical port
BulkSendHelper source ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
source.SetAttribute ("MaxBytes", UintegerValue(0)); //0 is maximum
ApplicationContainer sourceApps = source.Install(ap.Get(0));
sourceApps.Start (Seconds (0.0));
sourceApps.Stop (Seconds (240.0));
PacketSinkHelper sink ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), port));
ApplicationContainer sinkApps = sink.Install(stas.Get(0));
sinkApps.Start (Seconds (0.0));
sinkApps.Stop (Seconds (240.0));
// This line triggers the calculation of throughput per second, starting at second 0.
Simulator::Schedule (Seconds (0.0), &ThroughputPerSecond, sinkApps.Get(0), 0 , stas.Get(0));
// This line triggers the tracing of the modulation scheme (to get the data rate)
Config::Connect ("/NodeList/*/DeviceList/*/Phy/State/Tx", MakeCallback (&PhyTxTrace));
Simulator::Stop (Seconds (240.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
1 ответ
Я не знаком с NS3 на самом деле, но после просмотра вашего кода, может быть, если вы изменили эту строку
Simulator::Schedule (Seconds (0.0), &ThroughputPerSecond, sink1Apps, totalPacketsThrough, node);
в
Simulator::Schedule (Seconds (1.0), &ThroughputPerSecond, sink1Apps, totalPacketsThrough, node);
или любое значение, на которое вы хотите увеличить секунды, оно не может бесконечно зацикливаться.
Относительно того, почему вы получаете ошибочные данные; Боюсь, как я сказал выше, я не слишком знаком с NS3, поэтому не могу помочь в дальнейшем.