onOffApplication

这篇博客探讨了应用程序启动时首次数据传输的延迟计算,以及应用在暂停和重启时如何利用剩余时间信息来安排后续传输。例如,如果应用程序在3秒时启动,1000比特的数据包以500比特/秒的速率传输,则首次传输将在5秒发生,之后每2秒传输一次。若应用在4秒停止,5.5秒重新启动,第一次传输将延迟到6.5秒,因为系统保存了剩余的1秒传输时间。

Note: When an application is started, the first packet transmission occurs after a delay equal to (packet size/bit rate). Note also, when an application transitions into an off state in between packet transmissions, the remaining time until when the next transmission would have occurred is cached and is used when the application starts up again. Example: packet size = 1000 bits, bit rate = 500 bits/sec. If the application is started at time 3 seconds, the first packet transmission will be scheduled for time 5 seconds (3 + 1000/500) and subsequent transmissions at 2 second intervals. If the above application were instead stopped at time 4 seconds, and restarted at time 5.5 seconds, then the first packet would be sent at time 6.5 seconds, because when it was stopped at 4 seconds, there was only 1 second remaining until the originally scheduled transmission, and this time remaining information is cached and used to schedule the next transmission upon restarting.

/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ns3/applications-module.h" #include "ns3/internet-module.h" #include "ns3/mobility-module.h" #include "ns3/network-module.h" #include "ns3/point-to-point-module.h" #include "ns3/yans-wifi-helper.h" #include "ns3/command-line.h" #include "ns3/config.h" #include "ns3/internet-stack-helper.h" #include "ns3/ipv4-address-helper.h" #include "ns3/ipv4-global-routing-helper.h" #include "ns3/mobility-helper.h" #include "ns3/multi-model-spectrum-channel.h" #include "ns3/non-communicating-net-device.h" #include "ns3/on-off-helper.h" #include "ns3/packet-sink-helper.h" #include "ns3/packet-sink.h" #include "ns3/propagation-loss-model.h" #include "ns3/spectrum-wifi-helper.h" #include "ns3/ssid.h" #include "ns3/string.h" #include "ns3/udp-client-server-helper.h" #include "ns3/waveform-generator-helper.h" #include "ns3/waveform-generator.h" #include "ns3/wifi-net-device.h" #include "ns3/yans-wifi-channel.h" #include "ns3/yans-wifi-helper.h" #include "ns3/core-module.h" #include "ns3/spectrum-module.h" #include <ns3/spectrum-value.h> #include "ns3/log.h" #include "ns3/network-module.h" #include "ns3/applications-module.h" #include "ns3/global-router-interface.h" #include <iomanip> #include <cstdlib> #include <ctime> #include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <map> #include <cmath> #include <cstdlib> #include <algorithm> #include <iterator> #include "ns3/olsr-helper.h" using namespace ns3; NS_LOG_COMPONENT_DEFINE("multinodetest"); int waveformPower = 1e-3; std::vector<uint16_t> monitoredChannels = {36, 40, 44, 48, 52, 56, 60, 64}; std::map<uint16_t, double> channelFreqMap = { {36, 5180e9}, {40, 5200e9}, {44, 5220e9}, {48, 5240e9}, {52, 5260e9}, {56, 5280e9}, {60, 5300e9}, {64, 5320e9} }; std::map<uint16_t, uint32_t> channelToBandIndex; Ptr<SpectrumModel> CreateMultiChannelModel() { std::vector<BandInfo> bands; uint32_t index = 0; for (auto& channel : monitoredChannels) { NS_ABORT_MSG_IF(channelFreqMap.find(channel) == channelFreqMap.end(), "Undefined frequency for channel " << channel); BandInfo band; double centerFreq = channelFreqMap[channel]; band.fc = centerFreq; band.fl = centerFreq - 10e6; band.fh = centerFreq + 10e6; bands.push_back(band); channelToBandIndex[channel] = index++; } return Create<SpectrumModel>(bands); } void ProcessSpectrumData(Ptr<const SpectrumValue> spectrumData) { double time = Simulator::Now().GetSeconds(); std::cout << "\nSpectrum 1 at " << time << "s | "; // 遍历所有频段 for (auto it = spectrumData->ConstValuesBegin(); it != spectrumData->ConstValuesEnd(); ++it) { double powerWatts = (*it) * 20e6; // 计算总功率(W) double powerDbm = 10 * log10(powerWatts * 1000); // 转换为 dBm // 频段功率 std::cout << "band" << std::distance(spectrumData->ConstValuesBegin(), it) << ":" << std::fixed << std::setprecision(1) << powerDbm << "dBm | "; } std::cout << std::endl; } void ProcessSpectrumData_2(Ptr<const SpectrumValue> spectrumData) { double time = Simulator::Now().GetSeconds(); std::cout << "\nSpectrum 2 at " << time << "s | "; for (auto it = spectrumData->ConstValuesBegin(); it != spectrumData->ConstValuesEnd(); ++it) { double powerWatts = (*it) * 20e6; // 计算总功率(W) double powerDbm = 10 * log10(powerWatts * 1000); std::cout << "band" << std::distance(spectrumData->ConstValuesBegin(), it) << ":" << std::fixed << std::setprecision(1) << powerDbm << "dBm | "; } std::cout << std::endl; } void Signal(Ptr<SpectrumValue> jammingPsd, const std::string& jammingType) { static uint32_t currentBand = 0; static const std::vector<uint16_t> LChannel = {4,3,6,7,0,1,2,5}; int interval = 1; uint32_t targetBand = 0; for (uint32_t i = 0; i < monitoredChannels.size(); ++i) { (*jammingPsd)[i] = 0; } if (jammingType == "SWEEP") { targetBand = (currentBand + 1) % monitoredChannels.size(); currentBand = targetBand; } else if (jammingType == "SINGLE") { targetBand = 0; // } else if (jammingType == "NLSWEEP") { currentBand = (currentBand + 1) % LChannel.size(); targetBand = LChannel[currentBand]; } else if (jammingType == "RANDOM") { targetBand = rand() % monitoredChannels.size(); } else { NS_FATAL_ERROR("Unknown jamming type: " << jammingType); } (*jammingPsd)[targetBand] = 1e-6; NS_LOG_LOGIC("Jamming type: " << jammingType << " | Band: " << targetBand << " | Time: " << Simulator::Now().GetSeconds() << "s"); Simulator::Schedule(Seconds(interval), &Signal, jammingPsd, jammingType); } WifiPhy::ChannelTuple getChannelSetting(WifiStandard wifiStandard, WifiPhyBand phyband, int channelWidth, uint32_t channelId) { uint16_t frequency = 0; switch (wifiStandard) { case WIFI_STANDARD_80211ac: case WIFI_STANDARD_80211ax: default: // 不同wifi标准、不同频段和不同带宽都会导致base频率不同,11ac+5GHz: 5180/5190/5210/5250 for 20/40/80/160Mhz u_int16_t basefreq = 0; if(WIFI_PHY_BAND_2_4GHZ == phyband) { basefreq = 2402; } else if(WIFI_PHY_BAND_5GHZ == phyband) { basefreq = 5180; } else if(WIFI_PHY_BAND_6GHZ == phyband) { basefreq = 5180;//todo } else { std::cout<< "******phyband is not found! " << phyband << std::endl; //return ; } frequency = basefreq + channelWidth * channelId; if (channelWidth != 20 && channelWidth != 40 && channelWidth != 80 && channelWidth != 160) { std::cout<< "******Bandwidth is not compatible with standard" << std::endl; //return ; } break; } auto channelNum = std::get<0>(*WifiPhyOperatingChannel::FindFirst(0, frequency, channelWidth, wifiStandard, phyband)); uint32_t chnum = channelNum; std::cout<< "******channelId: " << channelId << " frequency: " << frequency << " channelnum: " << chnum << " channelwidth: " << channelWidth << " phyband: " << phyband << std::endl; return WifiPhy::ChannelTuple{chnum, channelWidth, (int)(phyband), (int)(0)}; } void FreChange(NodeContainer nodes,NodeContainer apnode,const std::string& ChangeType,const u_int16_t& plot){ uint16_t Channel = 0; if (ChangeType == "RANDOM") { Channel = std::rand() % monitoredChannels.size(); std::cout<<Channel<<std::endl; } else if (ChangeType == "FIXED") { Channel = 0; std::cout<<Channel<<std::endl; } else if (ChangeType == "Q") { std::cout << "Unknown type: " << std::endl; } else { std::cout << "Unknown type: " << std::endl; } for (auto end = nodes.End(), iter = nodes.Begin(); iter != end; ++iter) { Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>((*iter)->GetDevice(0)); Ptr<WifiPhy> wifiPhy = netDevice->GetPhy(); WifiPhy::ChannelTuple channelSetting = getChannelSetting(WIFI_STANDARD_80211ac, WIFI_PHY_BAND_5GHZ, 20, Channel); wifiPhy->SetOperatingChannel(channelSetting); } auto iter = apnode.Begin(); Ptr<WifiPhy> apPhy = DynamicCast<WifiNetDevice>((*iter)->GetDevice(1))->GetPhy(); WifiPhy::ChannelTuple channelSetting = getChannelSetting( WIFI_STANDARD_80211ac, WIFI_PHY_BAND_5GHZ, 20, Channel ); apPhy->SetOperatingChannel(channelSetting); Ptr<Node> Rxnode= nodes.Get(0); Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice>(Rxnode->GetDevice(0)); Ptr<WifiPhy> wifiPhy_ptr = netDevice->GetPhy(); std::cout<< "******wifi[0]:" << Rxnode->GetId() << "频率: " << wifiPhy_ptr->GetFrequency() << "Mhz" << std::endl; Ptr<WifiNetDevice> apSampleDevice = DynamicCast<WifiNetDevice>(apnode.Get(0)->GetDevice(1)); if (apSampleDevice) { std::cout << "AP[0] Frequency: " << apSampleDevice->GetPhy()->GetFrequency() << " MHz" << std::endl; } Simulator::Schedule(Seconds(plot), &FreChange,nodes,apnode,ChangeType,plot); } int main() { u_int16_t wifinode_num1 = 32; u_int16_t wifinode_num2 = 32; u_int16_t jammernode_num = 1; u_int16_t plot = 3; LogComponentEnable("UdpEchoClientApplication", LOG_LEVEL_INFO); LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO); LogComponentEnable("OnOffApplication", LOG_LEVEL_INFO); LogComponentEnable("PacketSink", LOG_LEVEL_INFO); //**********----network Topology----************// /*******----p2pnode----*******/ NodeContainer P2P_1; P2P_1.Create(2); PointToPointHelper P2Phelper; P2Phelper.SetDeviceAttribute("DataRate",StringValue("5Mbps")); P2Phelper.SetChannelAttribute("Delay",StringValue("2ms")); NetDeviceContainer P2P_1_1; P2P_1_1 = P2Phelper.Install(P2P_1); /*******----wifinode----*******/ NodeContainer wifi_1; wifi_1.Create(wifinode_num1); NodeContainer wifi_1_ap; wifi_1_ap.Add(P2P_1.Get(0)); NodeContainer wifi_2; wifi_2.Create(wifinode_num2); NodeContainer wifi_2_ap; wifi_2_ap.Add(P2P_1.Get(1)); Ptr<SpectrumModel>multiChannelModel = CreateMultiChannelModel(); Ptr<MultiModelSpectrumChannel> spectrumChannel = CreateObject<MultiModelSpectrumChannel>(); Ptr<FriisPropagationLossModel> lossModel = CreateObject<FriisPropagationLossModel> (); Ptr<NakagamiPropagationLossModel> fadingModel = CreateObject<NakagamiPropagationLossModel> (); lossModel->SetNext (fadingModel); spectrumChannel->AddPropagationLossModel (lossModel); Ptr<ConstantSpeedPropagationDelayModel> delayModel = CreateObject<ConstantSpeedPropagationDelayModel> (); spectrumChannel->SetPropagationDelayModel (delayModel); SpectrumWifiPhyHelper wifiPhy; wifiPhy.SetChannel(spectrumChannel); wifiPhy.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}")); wifiPhy.Set("TxPowerStart", DoubleValue(20)); // dBm wifiPhy.Set("TxPowerEnd", DoubleValue(20)); // 20dBm SpectrumWifiPhyHelper wifiPhy1; wifiPhy1.SetChannel(spectrumChannel); wifiPhy1.Set("ChannelSettings", StringValue("{36, 20, BAND_5GHZ, 0}")); wifiPhy1.Set("TxPowerStart", DoubleValue(20.0)); // dBm wifiPhy1.Set("TxPowerEnd", DoubleValue(20.0)); // dBm WifiMacHelper mac; Ssid zs = Ssid("zs"); Ssid sz = Ssid("sz"); WifiHelper wifi; NetDeviceContainer stawifi; mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(zs), "ActiveProbing", BooleanValue(false)); stawifi = wifi.Install(wifiPhy,mac,wifi_1); NetDeviceContainer apwifi; mac.SetType("ns3::ApWifiMac","Ssid",SsidValue(zs)); apwifi = wifi.Install(wifiPhy,mac,wifi_1_ap); NetDeviceContainer stawifi_2; mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(sz), "ActiveProbing", BooleanValue(false)); stawifi_2 = wifi.Install(wifiPhy1,mac,wifi_2); NetDeviceContainer apwifi_2; mac.SetType("ns3::ApWifiMac","Ssid",SsidValue(sz)); apwifi_2 = wifi.Install(wifiPhy1,mac,wifi_2_ap); MobilityHelper mobility; mobility.SetPositionAllocator("ns3::GridPositionAllocator", "MinX", DoubleValue(-7.0), "MinY", DoubleValue(-7.0), "DeltaX", DoubleValue(2.0), "DeltaY", DoubleValue(2.0), "GridWidth", UintegerValue(4), "LayoutType", StringValue("RowFirst")); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(wifi_1); Ptr<ListPositionAllocator> apPositionAlloc = CreateObject<ListPositionAllocator>(); apPositionAlloc->Add(Vector(-4, 0.0, 0.0)); mobility.SetPositionAllocator(apPositionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(wifi_1_ap); mobility.SetPositionAllocator("ns3::GridPositionAllocator", "MinX", DoubleValue(1.0), "MinY", DoubleValue(-7.0), "DeltaX", DoubleValue(2.0), "DeltaY", DoubleValue(2.0), "GridWidth", UintegerValue(4), "LayoutType", StringValue("RowFirst")); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(wifi_2); Ptr<ListPositionAllocator> ap_2_PositionAlloc = CreateObject<ListPositionAllocator>(); ap_2_PositionAlloc->Add(Vector(4, 0.0, 0.0)); mobility.SetPositionAllocator(ap_2_PositionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(wifi_2_ap); /*******----jamnode----*******/ NodeContainer jammernodes; jammernodes.Create(jammernode_num); Ptr<ListPositionAllocator> jamnode_PositionAlloc = CreateObject<ListPositionAllocator>(); jamnode_PositionAlloc->Add(Vector(0, 0.0, -3)); mobility.SetPositionAllocator(jamnode_PositionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(jammernodes); Ptr<SpectrumValue> jammingPsd = Create<SpectrumValue>(multiChannelModel); WaveformGeneratorHelper jammerHelper; jammerHelper.SetChannel(spectrumChannel); jammerHelper.SetTxPowerSpectralDensity(jammingPsd);//w/hz jammerHelper.SetPhyAttribute("Period", TimeValue(Seconds(1))); jammerHelper.SetPhyAttribute("DutyCycle", DoubleValue(1)); NetDeviceContainer waveformGeneratorDevices =jammerHelper.Install(jammernodes); Ptr<WaveformGenerator> waveformGenerator = waveformGeneratorDevices.Get(0) ->GetObject<NonCommunicatingNetDevice>() ->GetPhy() ->GetObject<WaveformGenerator>(); waveformGenerator->Start(); /*******----spectrumanalyzerhelper----*******/ SpectrumAnalyzerHelper spectrumAnalyzerHelper; spectrumAnalyzerHelper.SetChannel(spectrumChannel); spectrumAnalyzerHelper.SetRxSpectrumModel(multiChannelModel); spectrumAnalyzerHelper.SetPhyAttribute("Resolution", TimeValue(MilliSeconds(10))); spectrumAnalyzerHelper.SetPhyAttribute("NoisePowerSpectralDensity", DoubleValue(1e-15)); NetDeviceContainer spectrumAnalyzerDevices = spectrumAnalyzerHelper.Install(wifi_1_ap); Ptr<SpectrumAnalyzer> analyzer = DynamicCast<SpectrumAnalyzer>( spectrumAnalyzerDevices.Get(0)->GetObject<NonCommunicatingNetDevice>()->GetPhy() ); Simulator::Schedule(Seconds(9.0), &SpectrumAnalyzer::Start, analyzer); analyzer->TraceConnectWithoutContext("AveragePowerSpectralDensityReport", MakeCallback(&ProcessSpectrumData)); NetDeviceContainer spectrumAnalyzerDevices_2 = spectrumAnalyzerHelper.Install(wifi_2_ap); Ptr<SpectrumAnalyzer> analyzer_2 = DynamicCast<SpectrumAnalyzer>( spectrumAnalyzerDevices_2.Get(0)->GetObject<NonCommunicatingNetDevice>()->GetPhy() ); //Simulator::Schedule(Seconds(9.0), &SpectrumAnalyzer::Start, analyzer_2); //analyzer_2->TraceConnectWithoutContext("AveragePowerSpectralDensityReport", MakeCallback(&ProcessSpectrumData_2)); //**********----Internet layer----************// InternetStackHelper stack; stack.SetRoutingHelper(OlsrHelper()); stack.Install(wifi_1); stack.Install(wifi_2); stack.Install(P2P_1); Ipv4AddressHelper address; address.SetBase("192.168.1.0", "255.255.255.252"); address.Assign(P2P_1_1); address.SetBase("10.1.6.0","255.255.255.0"); Ipv4InterfaceContainer wifi_interface_1; wifi_interface_1 = address.Assign(stawifi); address.Assign(apwifi); address.SetBase("10.1.7.0","255.255.255.0"); Ipv4InterfaceContainer wifi_interface; wifi_interface = address.Assign(stawifi_2); address.Assign(apwifi_2); //**********----APP layer----************// //********** cluster A to B communication UdpEchoServerHelper echoServer(9); ApplicationContainer serverApps = echoServer.Install(wifi_2.Get(3)); UdpEchoClientHelper echoClient(wifi_interface.GetAddress(3), 9); echoClient.SetAttribute("MaxPackets", UintegerValue(1)); echoClient.SetAttribute("Interval", TimeValue(Seconds(5))); echoClient.SetAttribute("PacketSize", UintegerValue(1024)); ApplicationContainer clientApps = echoClient.Install(wifi_1.Get(4)); /*serverApps.Start(Seconds(11.0)); serverApps.Stop(Seconds(14.0)); clientApps.Start(Seconds(12.5)); clientApps.Stop(Seconds(14.0));*/ //********** cluster A inner communication ApplicationContainer serverApp; uint16_t port = 5000; Address localAddress(InetSocketAddress(Ipv4Address::GetAny(), port)); PacketSinkHelper packetSinkHelper("ns3::UdpSocketFactory", localAddress); serverApp = packetSinkHelper.Install(wifi_1.Get(0)); serverApp.Start(Seconds(0.0)); serverApp.Stop(Seconds(100)); OnOffHelper onoff("ns3::UdpSocketFactory", Ipv4Address::GetAny()); onoff.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]")); onoff.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]")); onoff.SetAttribute("PacketSize", UintegerValue(1024)); onoff.SetAttribute("DataRate", DataRateValue(1024 * 8 * 3)); // bit/s AddressValue remoteAddress(InetSocketAddress(wifi_interface_1.GetAddress(0), port)); onoff.SetAttribute("Remote", remoteAddress); std::vector<ApplicationContainer> clientApp(wifinode_num1); for(int i = 1; i < wifinode_num1;++i){ clientApp[i] = onoff.Install(wifi_1.Get(i)); } for (uint32_t i = 1; i < wifinode_num1; ++i) { // fre_change 0~1 s // data send 1~plot s clientApp[i].Start(Seconds(i * plot + (11 - plot))); clientApp[i].Stop(Seconds(i * plot + 9.99)); } std::ofstream logFile("simulation_AtoA.txt"); std::clog.rdbuf(logFile.rdbuf()); // ns-3 默认用 clog 输出日志 P2Phelper.EnablePcap("p2p_1",P2P_1_1.Get(0)); P2Phelper.EnablePcap("p2p_1",P2P_1_1.Get(1)); wifiPhy.EnablePcap("apwifi",apwifi_2.Get(0)); wifiPhy.EnablePcap("wifi_1",stawifi_2.Get(3)); //**********----simulation layer----************// Simulator::Schedule(Seconds(9),&Signal,jammingPsd,"SINGLE"); Simulator::Schedule(Seconds(9),&FreChange,wifi_1,wifi_1_ap,"FIXED",plot); Simulator::Stop(Seconds(20)); Simulator::Run(); Simulator::Destroy(); return 0; } 看看哪里的问题
07-29
我想请你编写一份用ns3.45完成的网络仿真代码,不需要兼容其他版本,请在后续的回答中给代码加上详细注释,并且避免使用//,而是使用/**/,代码的目标:分析一对AP-STA架构下不同因素对网络性能的影响。包含四个实验模块:射频配置对性能的影响,跑流方式对性能的影响,距离对性能的影响,网络质量指标收集。编写时请多用助手类,避免使用固定速率,而是用某一个现有的速率调用算法。在编写时请参考下方的wifi仿真代码,仿造其代码风格和助手类的使用: /* * Copyright (c) 2009 MIRKO BANCHI * * SPDX-License-Identifier: GPL-2.0-only * * Authors: Mirko Banchi <mk.banchi@gmail.com> * Sebastien Deronne <sebastien.deronne@gmail.com> */ #include "ns3/attribute-container.h" #include "ns3/boolean.h" #include "ns3/command-line.h" #include "ns3/config.h" #include "ns3/double.h" #include "ns3/enum.h" #include "ns3/ht-phy.h" #include "ns3/internet-stack-helper.h" #include "ns3/ipv4-address-helper.h" #include "ns3/ipv4-global-routing-helper.h" #include "ns3/log.h" #include "ns3/mobility-helper.h" #include "ns3/on-off-helper.h" #include "ns3/packet-sink-helper.h" #include "ns3/packet-sink.h" #include "ns3/ssid.h" #include "ns3/string.h" #include "ns3/tuple.h" #include "ns3/udp-client-server-helper.h" #include "ns3/udp-server.h" #include "ns3/uinteger.h" #include "ns3/yans-wifi-channel.h" #include "ns3/yans-wifi-helper.h" #include <algorithm> #include <vector> // This is a simple example in order to show how to configure an IEEE 802.11n Wi-Fi network. // // It outputs the UDP or TCP goodput for every HT MCS value, which depends on the MCS value (0 to // 7), the channel width (20 or 40 MHz) and the guard interval (long or short). The PHY bitrate is // constant over all the simulation run. The user can also specify the distance between the access // point and the station: the larger the distance the smaller the goodput. // // The simulation assumes a single station in an infrastructure network: // // STA AP // * * // | | // n1 n2 // // Packets in this simulation belong to BestEffort Access Class (AC_BE). using namespace ns3; NS_LOG_COMPONENT_DEFINE("ht-wifi-network"); int main(int argc, char* argv[]) { bool udp{true}; bool useRts{false}; Time simulationTime{"10s"}; meter_u distance{1.0}; double frequency{5}; // whether 2.4 or 5 GHz std::string mcsStr; std::vector<uint64_t> mcsValues; int channelWidth{-1}; // in MHz, -1 indicates an unset value int guardInterval{-1}; // in nanoseconds, -1 indicates an unset value double minExpectedThroughput{0.0}; double maxExpectedThroughput{0.0}; CommandLine cmd(__FILE__); cmd.AddValue("frequency", "Whether working in the 2.4 or 5.0 GHz band (other values gets rejected)", frequency); cmd.AddValue("distance", "Distance in meters between the station and the access point", distance); cmd.AddValue("simulationTime", "Simulation time", simulationTime); cmd.AddValue("udp", "UDP if set to 1, TCP otherwise", udp); cmd.AddValue("useRts", "Enable/disable RTS/CTS", useRts); cmd.AddValue( "mcs", "list of comma separated MCS values to test; if unset, all MCS values (0-7) are tested", mcsStr); cmd.AddValue( "channelWidth", "if set, limit testing to a specific channel width expressed in MHz (20 or 40 MHz)", channelWidth); cmd.AddValue("guardInterval", "if set, limit testing to a specific guard interval duration expressed in " "nanoseconds (800 or 400 ns)", guardInterval); cmd.AddValue("minExpectedThroughput", "if set, simulation fails if the lowest throughput is below this value", minExpectedThroughput); cmd.AddValue("maxExpectedThroughput", "if set, simulation fails if the highest throughput is above this value", maxExpectedThroughput); cmd.Parse(argc, argv); if (useRts) { Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue("0")); } double prevThroughput[8] = {0}; std::cout << "MCS value" << "\t\t" << "Channel width" << "\t\t" << "short GI" << "\t\t" << "Throughput" << '\n'; uint8_t minMcs = 0; uint8_t maxMcs = 7; if (mcsStr.empty()) { for (uint8_t mcs = minMcs; mcs <= maxMcs; ++mcs) { mcsValues.push_back(mcs); } } else { AttributeContainerValue<UintegerValue, ',', std::vector> attr; auto checker = DynamicCast<AttributeContainerChecker>(MakeAttributeContainerChecker(attr)); checker->SetItemChecker(MakeUintegerChecker<uint8_t>()); attr.DeserializeFromString(mcsStr, checker); mcsValues = attr.Get(); std::sort(mcsValues.begin(), mcsValues.end()); } int minChannelWidth = 20; int maxChannelWidth = 40; if ((channelWidth != -1) && ((channelWidth < minChannelWidth) || (channelWidth > maxChannelWidth))) { NS_FATAL_ERROR("Invalid channel width: " << channelWidth << " MHz"); } if (channelWidth >= minChannelWidth && channelWidth <= maxChannelWidth) { minChannelWidth = channelWidth; maxChannelWidth = channelWidth; } int minGi = 400; int maxGi = 800; if (guardInterval >= minGi && guardInterval <= maxGi) { minGi = guardInterval; maxGi = guardInterval; } for (const auto mcs : mcsValues) { uint8_t index = 0; double previous = 0; for (int width = minChannelWidth; width <= maxChannelWidth; width *= 2) // MHz { for (int gi = maxGi; gi >= minGi; gi /= 2) // Nanoseconds { const auto sgi = (gi == 400); uint32_t payloadSize; // 1500 byte IP packet if (udp) { payloadSize = 1472; // bytes } else { payloadSize = 1448; // bytes Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(payloadSize)); } NodeContainer wifiStaNode; wifiStaNode.Create(1); NodeContainer wifiApNode; wifiApNode.Create(1); YansWifiChannelHelper channel = YansWifiChannelHelper::Default(); YansWifiPhyHelper phy; phy.SetChannel(channel.Create()); WifiMacHelper mac; WifiHelper wifi; std::ostringstream ossControlMode; if (frequency == 5.0) { ossControlMode << "OfdmRate"; wifi.SetStandard(WIFI_STANDARD_80211n); } else if (frequency == 2.4) { wifi.SetStandard(WIFI_STANDARD_80211n); ossControlMode << "ErpOfdmRate"; Config::SetDefault("ns3::LogDistancePropagationLossModel::ReferenceLoss", DoubleValue(40.046)); } else { NS_FATAL_ERROR("Wrong frequency value!"); } auto nonHtRefRateMbps = HtPhy::GetNonHtReferenceRate(mcs) / 1e6; ossControlMode << nonHtRefRateMbps << "Mbps"; std::ostringstream ossDataMode; ossDataMode << "HtMcs" << mcs; wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode", StringValue(ossDataMode.str()), "ControlMode", StringValue(ossControlMode.str())); // Set guard interval wifi.ConfigHtOptions("ShortGuardIntervalSupported", BooleanValue(sgi)); Ssid ssid = Ssid("ns3-80211n"); AttributeContainerValue< TupleValue<UintegerValue, UintegerValue, EnumValue<WifiPhyBand>, UintegerValue>, ';'> channelValue; WifiPhyBand band = (frequency == 5.0 ? WIFI_PHY_BAND_5GHZ : WIFI_PHY_BAND_2_4GHZ); channelValue.Set(WifiPhy::ChannelSegments{{0, width, band, 0}}); mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid)); phy.Set("ChannelSettings", channelValue); NetDeviceContainer staDevice; staDevice = wifi.Install(phy, mac, wifiStaNode); mac.SetType("ns3::ApWifiMac", "EnableBeaconJitter", BooleanValue(false), "Ssid", SsidValue(ssid)); NetDeviceContainer apDevice; apDevice = wifi.Install(phy, mac, wifiApNode); int64_t streamNumber = 150; streamNumber += WifiHelper::AssignStreams(apDevice, streamNumber); streamNumber += WifiHelper::AssignStreams(staDevice, streamNumber); // mobility. MobilityHelper mobility; Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>(); positionAlloc->Add(Vector(0.0, 0.0, 0.0)); positionAlloc->Add(Vector(distance, 0.0, 0.0)); mobility.SetPositionAllocator(positionAlloc); mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel"); mobility.Install(wifiApNode); mobility.Install(wifiStaNode); /* Internet stack*/ InternetStackHelper stack; stack.Install(wifiApNode); stack.Install(wifiStaNode); streamNumber += stack.AssignStreams(wifiApNode, streamNumber); streamNumber += stack.AssignStreams(wifiStaNode, streamNumber); Ipv4AddressHelper address; address.SetBase("192.168.1.0", "255.255.255.0"); Ipv4InterfaceContainer staNodeInterface; Ipv4InterfaceContainer apNodeInterface; staNodeInterface = address.Assign(staDevice); apNodeInterface = address.Assign(apDevice); /* Setting applications */ const auto maxLoad = HtPhy::GetDataRate(mcs, MHz_u{static_cast<double>(width)}, NanoSeconds(sgi ? 400 : 800), 1); ApplicationContainer serverApp; if (udp) { // UDP flow uint16_t port = 9; UdpServerHelper server(port); serverApp = server.Install(wifiStaNode.Get(0)); streamNumber += server.AssignStreams(wifiStaNode.Get(0), streamNumber); serverApp.Start(Seconds(0)); serverApp.Stop(simulationTime + Seconds(1)); const auto packetInterval = payloadSize * 8.0 / maxLoad; UdpClientHelper client(staNodeInterface.GetAddress(0), port); client.SetAttribute("MaxPackets", UintegerValue(4294967295U)); client.SetAttribute("Interval", TimeValue(Seconds(packetInterval))); client.SetAttribute("PacketSize", UintegerValue(payloadSize)); ApplicationContainer clientApp = client.Install(wifiApNode.Get(0)); streamNumber += client.AssignStreams(wifiApNode.Get(0), streamNumber); clientApp.Start(Seconds(1)); clientApp.Stop(simulationTime + Seconds(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)); streamNumber += packetSinkHelper.AssignStreams(wifiStaNode.Get(0), streamNumber); serverApp.Start(Seconds(0)); serverApp.Stop(simulationTime + Seconds(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(maxLoad)); AddressValue remoteAddress( InetSocketAddress(staNodeInterface.GetAddress(0), port)); onoff.SetAttribute("Remote", remoteAddress); ApplicationContainer clientApp = onoff.Install(wifiApNode.Get(0)); streamNumber += onoff.AssignStreams(wifiApNode.Get(0), streamNumber); clientApp.Start(Seconds(1)); clientApp.Stop(simulationTime + Seconds(1)); } Ipv4GlobalRoutingHelper::PopulateRoutingTables(); Simulator::Stop(simulationTime + Seconds(1)); Simulator::Run(); auto rxBytes = 0.0; if (udp) { rxBytes = payloadSize * DynamicCast<UdpServer>(serverApp.Get(0))->GetReceived(); } else { rxBytes = DynamicCast<PacketSink>(serverApp.Get(0))->GetTotalRx(); } auto throughput = (rxBytes * 8) / simulationTime.GetMicroSeconds(); // Mbit/s Simulator::Destroy(); std::cout << mcs << "\t\t\t" << width << " MHz\t\t\t" << std::boolalpha << sgi << "\t\t\t" << throughput << " Mbit/s" << std::endl; // test first element if (mcs == minMcs && width == 20 && !sgi) { if (throughput < minExpectedThroughput) { NS_FATAL_ERROR("Obtained throughput " << throughput << " is not expected!"); } } // test last element if (mcs == maxMcs && width == 40 && sgi) { if (maxExpectedThroughput > 0 && throughput > maxExpectedThroughput) { NS_FATAL_ERROR("Obtained throughput " << throughput << " is not expected!"); } } // test previous throughput is smaller (for the same mcs) if (throughput > previous) { previous = throughput; } else { NS_FATAL_ERROR("Obtained throughput " << throughput << " is not expected!"); } // test previous throughput is smaller (for the same channel width and GI) if (throughput > prevThroughput[index]) { prevThroughput[index] = throughput; } else { NS_FATAL_ERROR("Obtained throughput " << throughput << " is not expected!"); } index++; } } } return 0; }
最新发布
08-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值