在研究路由问题的时候遇到了这个问题,小结一下
一、路由协议栈修改
参考ns3之使用Ipv4ListRouting在一个节点上插入不同的路由协议_ipv4listroutinghelper-优快云博客
PS.
1.记得添加头文件
2.这一段代码在创建nodes、channels之后,分配ip地址之前
3. 数字越大,优先级越高
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/ipv4-list-routing-helper.h"
// InternetStackHelper internet;
// internet.Install (nodes);
//安装协议栈
Ipv4GlobalRoutingHelper globalRouting;
Ipv4StaticRoutingHelper staticRouting;
Ipv4ListRoutingHelper list;
list.Add (staticRouting, 20);//设置路由优先级,优先使用静态路由协议
list.Add (globalRouting, 10);
InternetStackHelper internet;
internet.SetRoutingHelper (list);
internet.Install (nodes);
二、分配IP地址
给静态路由涉及到的链路增加Ipv4InterfaceContainer,这样方便之后单独设置路由节点,这一段也可以省略
//分配IP地址
NS_LOG_INFO ("Assign IP Addresses.");
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0","255.255.255.0");
ipv4.Assign(d0d1);
Ipv4InterfaceContainer i0i1 = ipv4.Assign(d0d1);
三、 配置具体的静态路由路径
需要为每个涉及到的节点制定转发流量的方向
参考NS3 的 ipv4-static-routing-test-suite 源码分析_ns3源码-优快云博客
参数解析:AddHostRouteTo(Ipv4Address (目的节点IP地址:"10.1.1.2"), Ipv4Address (下一跳节点IP地址:"10.1.10.3"), 当前节点到下一跳节点的接口:1)
PS.
①节点的IP地址可以根据分配时候的参数确定,比如是"10.1.1.0"子网下的节点,就按照10.1.1.1、10.1.1.2这样按照节点次序依次分配,接口同理,可以再通过可视化模块验证下IP地址
②目的节点IP地址是默认的最小地址,就是最先分配的地址,在这里被卡了好久
③还需要给别的节点用全局路由填充路由表,不然只有这一条流会运行
// 获取每个节点的Ipv4实例和静态路由协议实例
// 8-5-2-3-0-1
Ptr<Ipv4> ipv4_8 = nodes.Get(8)->GetObject<Ipv4>();
Ptr<Ipv4StaticRouting> staticRouting_8 = staticRouting.GetStaticRouting(ipv4_8);
// // path1:8-5-2-3-0-1
staticRouting_8->AddHostRouteTo(Ipv4Address ("10.1.1.2"), Ipv4Address ("10.1.10.3"), 1);
staticRouting_5->AddHostRouteTo(Ipv4Address ("10.1.1.2"), Ipv4Address ("10.1.5.1"), 1);
staticRouting_2->AddHostRouteTo(Ipv4Address ("10.1.1.2"), Ipv4Address ("10.1.4.2"), 1);
staticRouting_3->AddHostRouteTo(Ipv4Address ("10.1.1.2"), Ipv4Address ("10.1.2.1"), 1);
staticRouting_0->AddHostRouteTo(Ipv4Address ("10.1.1.2"), Ipv4Address ("10.1.1.2"), 1);
// 其余节点的路由表也要填充
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
四、设置流量模型
这里采用的是on\off流量模型,主要参数OnTime、OffTime、DataRate、PacketSize
PS.注意发送方、接收方的定义,和UdpEchoClientHelper不太一样
1.定义监听端口port相关的是接收方
2.install流量模型的是发送方
NS_LOG_INFO ("Create Applications.");
uint16_t port = 9; // Discard port (RFC 863)
UdpEchoServerHelper echoServer (9);
//业务1:onoff,8-1
//接收方:InetSocketAddress
OnOffHelper onoff ("ns3::UdpSocketFactory",
InetSocketAddress (i0i1.GetAddress (1), port));
onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
onoff.SetAttribute ("DataRate", StringValue ("1Mbps"));
onoff.SetAttribute ("PacketSize", UintegerValue (1024));
// 发送方:onoff.install\sink.install
ApplicationContainer clientapps = onoff.Install (nodes.Get (8));
clientapps.Start (Seconds (1.0));
clientapps.Stop (Seconds (10.0));
PacketSinkHelper sink ("ns3::UdpSocketFactory",
Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
ApplicationContainer serverapps = sink.Install (nodes.Get (8));
serverapps.Start (Seconds (1.0));
serverapps.Stop (Seconds (10.0));
五、输出性能指标
这里使用的是Flowmonitor,参考ns3利用FlowMonitor进行网络性能分析 - 代码先锋网
PS.
1.注意添加头文件
2.flowmonitor生成的xml和可视化的xml不一样,注意打开方式,否则NetAnim会闪退
#include "ns3/flow-monitor-module.h"
#include "ns3/flow-monitor-helper.h"
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
NS_LOG_INFO ("Run Simulation.");
Simulator::Stop(Seconds(10.0));
Simulator::Run();
monitor->CheckForLostPackets();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier());
FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
for (auto it = stats.begin(); it != stats.end(); ++it) {
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(it->first);
std::cout << "Flow ID: " << it->first << " Source IP: " << t.sourceAddress << " Destination IP: " << t.destinationAddress << std::endl;
std::cout << " Tx Packets: " << it->second.txPackets << " Rx Packets: " << it->second.rxPackets << std::endl;
// std::cout << " Lost Packets: " << it->second.lostPackets << std::endl;
std::cout << " Lost Packets: " << it->second.txPackets-it->second.rxPackets << std::endl;
std::cout << " Delay (s): " << it->second.delaySum.GetSeconds() << std::endl;
std::cout << " Jitter (s): " << it->second.jitterSum.GetSeconds() << std::endl;
std::cout << " Throughput (bps): " << it->second.rxBytes * 8.0 / 10.0 << std::endl; // 除以仿真时长得到平均吞吐量
}
//flowmonitor生成的xml和可视化的不一样,注意打开方式
monitor->SerializeToXmlFile("demo6.xml", true, true);
可视化仿真结果如下:
Flow-monitor读取xml结果如下: