/*
* Copyright (c) 2016 SEBASTIEN DERONNE
*
* SPDX-License-Identifier: GPL-2.0-only
*
* Author: Sebastien Deronne <sebastien.deronne@gmail.com>
* Modified for MinstrelHt: [Your Name]
*/
#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/he-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/minstrel-ht-wifi-manager.h"
#include "ns3/mobility-helper.h"
#include "ns3/multi-model-spectrum-channel.h"
#include "ns3/on-off-helper.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/packet-sink.h"
#include "ns3/spectrum-wifi-helper.h"
#include "ns3/ssid.h"
#include "ns3/string.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"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("he-wifi-network");
int
main(int argc, char* argv[])
{
// 固定参数设置
bool udp = true;
// bool downlink = true;
meter_u distance = 30.0;
Time simulationTime = Seconds(10);
// std::size_t nStations = 1;
// uint32_t payloadSize = 700; // bytes
// double frequency = 5; // 5GHz频段
// int channelWidth = 80; // MHz (固定80MHz带宽)
int guardInterval = 800; // ns (固定800ns GI)
// 命令行参数解析
CommandLine cmd(__FILE__);
cmd.AddValue("distance", "距离(米)", distance);
cmd.AddValue("simulationTime", "仿真时间", simulationTime);
cmd.AddValue("udp", "UDP协议(默认true)", udp);
cmd.Parse(argc, argv);
uint32_t payloadSize; // 1500 byte IP packet
if (udp)
{
payloadSize = 1472; // bytes
}
else
{
payloadSize = 1448; // bytes
Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(payloadSize));
}
// 创建节点
NodeContainer wifiStaNodes;
wifiStaNodes.Create(1);
NodeContainer wifiApNode;
wifiApNode.Create(1);
// 配置Wi-Fi
WifiMacHelper mac;
WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211ax);
// 使用MinstrelHt速率选择算法
wifi.SetRemoteStationManager("ns3::MinstrelHtWifiManager");
Ssid ssid = Ssid("minstrelht-demo");
wifi.ConfigHeOptions("GuardInterval", TimeValue(NanoSeconds(guardInterval)));
// 配置信道和物理层
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
YansWifiPhyHelper phy;
phy.SetChannel(channel.Create());
/*
std::string channelStr = "{0, " + std::to_string(channelWidth) + ", BAND_5GHZ, 0}";
phy.Set("ChannelSettings", StringValue(channelStr));
*/
// 安装站点设备
mac.SetType("ns3::StaWifiMac", "Ssid", SsidValue(ssid));
NetDeviceContainer staDevices = wifi.Install(phy, mac, wifiStaNodes);
// 安装AP设备
mac.SetType("ns3::ApWifiMac", "Ssid", SsidValue(ssid));
NetDeviceContainer apDevice = wifi.Install(phy, mac, wifiApNode);
// 移动性配置
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator>();
positionAlloc->Add(Vector(0.0, 0.0, 0.0)); // AP位置
positionAlloc->Add(Vector(distance, 0.0, 0.0)); // STA位置
mobility.SetPositionAllocator(positionAlloc);
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(wifiApNode);
mobility.Install(wifiStaNodes);
// 网络协议栈
InternetStackHelper stack;
stack.Install(wifiApNode);
stack.Install(wifiStaNodes);
// IP地址分配
Ipv4AddressHelper address;
address.SetBase("192.168.1.0", "255.255.255.0");
Ipv4InterfaceContainer staNodeInterfaces = address.Assign(staDevices);
Ipv4InterfaceContainer apNodeInterface = address.Assign(apDevice);
// 下行流量应用设置
ApplicationContainer serverApp;
uint16_t port = udp ? 9 : 50000;
// 服务器安装在STA节点
if (udp)
{
UdpServerHelper server(port);
serverApp = server.Install(wifiStaNodes);
}
else
{
PacketSinkHelper packetSink("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), port));
serverApp = packetSink.Install(wifiStaNodes);
}
serverApp.Start(Seconds(0.0));
serverApp.Stop(simulationTime + Seconds(1.0));
// 客户端安装在AP节点
ApplicationContainer clientApps;
if (udp)
{
UdpClientHelper client(staNodeInterfaces.GetAddress(0), port);
client.SetAttribute("MaxPackets", UintegerValue(0xFFFFFFFF));
client.SetAttribute("Interval", TimeValue(Time("0.0001"))); // 高发送速率
client.SetAttribute("PacketSize", UintegerValue(payloadSize));
clientApps.Add(client.Install(wifiApNode.Get(0)));
}
else
{
OnOffHelper client("ns3::TcpSocketFactory",
InetSocketAddress(staNodeInterfaces.GetAddress(0), port));
client.SetAttribute("PacketSize", UintegerValue(payloadSize));
client.SetAttribute("DataRate", DataRateValue(DataRate("100Mbps")));
clientApps.Add(client.Install(wifiApNode.Get(0)));
}
clientApps.Start(Seconds(1.0));
clientApps.Stop(simulationTime + Seconds(1.0));
// 路由和仿真控制
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
Simulator::Stop(simulationTime + Seconds(1.0));
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
std::cout << "------------------------------------------------" << std::endl;
std::cout << "下行吞吐量结果 (MinstrelHt算法)" << std::endl;
std::cout << "距离: " << distance << " 米" << std::endl;
// std::cout << "带宽: " << channelWidth << " MHz" << std::endl;
std::cout << "协议: " << (udp ? "UDP" : "TCP") << std::endl;
std::cout << "吞吐量: " << throughput << " Mbps" << std::endl;
std::cout << "------------------------------------------------" << std::endl;
Simulator::Destroy();
return 0;
}
为什么udp吞吐率测试会出现距离越远吞吐率越高的现象,请帮我检查代码