/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2009 IITP RAS
*
* 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
*
* This is an example script for AODV manet routing protocol.
*
* Authors: Pavel Boyko <boyko@iitp.ru>
*/
#include <iostream>
#include <cmath>
#include "ns3/aodv-module.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/v4ping-helper.h"
#include "ns3/yans-wifi-helper.h"
using namespace ns3;
/**
* \ingroup aodv-examples
* \ingroup examples
* \brief Test script.
*
* This script creates 1-dimensional grid topology and then ping last node from the first one: 创建一维的网络拓扑,第一个节点ping最后一个节点
*
* [10.0.0.1] <-- step --> [10.0.0.2] <-- step --> [10.0.0.3] <-- step --> [10.0.0.4]
*
* ping 10.0.0.4
*
* When 1/3 of simulation time has elapsed, one of the nodes is moved out of
* range, thereby breaking the topology. By default, this will result in
* only 34 of 100 pings being received. If the step size is reduced
* to cover the gap, then all pings can be received.
* 当经过1/3的模拟时间后,其中一个节点被移出范围,从而破坏拓扑
* 默认情况下,这将导致100个ping中只有34个被接收。
* 如果减小步长以覆盖间隙,那么所有的ping都能被接收
*/
class AodvExample {
public:
AodvExample();
/**
* \brief Configure script parameters
* \param argc is the command line argument count
* \param argv is the command line arguments
* \return true on successful configuration
*/
bool Configure(int argc, char **argv);
/// Run simulation
void Run();
/**
* Report results
* \param os the output stream
*/
void Report(std::ostream &os);
private:
// parameters
/// Number of nodes
uint32_t size;
/// Distance between nodes, meters 节点间隔,单位:米
double step;
/// Simulation time, seconds
double totalTime;
/// Write per-device PCAP traces if true 如果pcap 设置为true,则每个节点生成一个pcap 文件
bool pcap;
/// Print routes if true
bool printRoutes;
// network
/// nodes used in the example
NodeContainer nodes;
/// devices used in the example
NetDeviceContainer devices;
/// interfaces used in the example
Ipv4InterfaceContainer interfaces;
private:
/// Create the nodes
void CreateNodes();
/// Create the devices
void CreateDevices();
/// Create the network
void InstallInternetStack();
/// Create the simulation applications
void InstallApplications();
};
int main(int argc, char **argv) {
AodvExample test;
if (!test.Configure(argc, argv))
NS_FATAL_ERROR("Configuration failed. Aborted.");
test.Run();
test.Report(std::cout);
return 0;
}
//-----------------------------------------------------------------------------
AodvExample::AodvExample() :
size(12), step(50), totalTime(10), pcap(true), printRoutes(true) {
}
bool AodvExample::Configure(int argc, char **argv) {
// Enable AODV logs by default. Comment this if too noisy
// LogComponentEnable("AodvRoutingProtocol", LOG_LEVEL_ALL);
SeedManager::SetSeed(12345);
CommandLine cmd(__FILE__);
cmd.AddValue("pcap", "Write PCAP traces.", pcap);
cmd.AddValue("printRoutes", "Print routing table dumps.", printRoutes);
cmd.AddValue("size", "Number of nodes.", size);
cmd.AddValue("time", "Simulation time, s.", totalTime);
cmd.AddValue("step", "Grid step, m", step);
cmd.Parse(argc, argv);
return true;
}
void AodvExample::Run() {
// Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", UintegerValue (1)); // enable rts cts all the time.
CreateNodes(); //创建节点并为节点分配初始位置和移动模型
CreateDevices(); //为节点安装wifi网络设备,包括设置信道,设置物理层协,设置Mac 层
InstallInternetStack(); //为节点安装协议栈,为网络设备分配IP地址
InstallApplications(); //为第一个节点安装ping 应用,ping 最后一个节点
std::cout << "Starting simulation for " << totalTime << " s ...\n";
Simulator::Stop(Seconds(totalTime));
Simulator::Run();
Simulator::Destroy();
}
void AodvExample::Report(std::ostream&) {
}
//Jerry:创建节点并为节点分配初始位置和移动模型
void AodvExample::CreateNodes() {
std::cout << "Creating " << (unsigned) size << " nodes " << step
<< " m apart.\n";
nodes.Create(size);
// Name nodes,命名节点
for (uint32_t i = 0; i < size; ++i) {
std::ostringstream os;
os << "node-" << i;
Names::Add(os.str(), nodes.Get(i));
}
// Create static grid
/*
* (58条消息) ns-3 GridPositionAllocator 属性解释_ns-3网络模拟,ns3路由协议仿真-优快云博客
* https://blog.youkuaiyun.com/barcodegun/article/details/6981475
*/
MobilityHelper mobility;
//设置位置分配器
mobility.SetPositionAllocator("ns3::GridPositionAllocator", "MinX",
DoubleValue(0.0), "MinY", DoubleValue(0.0), "DeltaX",
DoubleValue(step), "DeltaY", DoubleValue(step), "GridWidth",
UintegerValue(3), "LayoutType", StringValue("RowFirst"));
//设置移动模型
// mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.SetMobilityModel("ns3::RandomWalk2dMobilityModel", "Bounds",
RectangleValue(Rectangle(-5000, 5000, -5000, 5000)));
mobility.Install(nodes);
}
//为节点安装wifi网络设备,包括设置信道,设置物理层协,设置Mac 层
void AodvExample::CreateDevices() {
//设置wifi 协议的mac 层
WifiMacHelper wifiMac;
wifiMac.SetType("ns3::AdhocWifiMac");
YansWifiPhyHelper wifiPhy; //Wifi 协议的物理层实现
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default();//用来创建拥有默认PropagationLoss和PropagationDelay模型的WifiChannel
wifiPhy.SetChannel(wifiChannel.Create());
WifiHelper wifi;
wifi.SetRemoteStationManager("ns3::ConstantRateWifiManager", "DataMode",
StringValue("OfdmRate6Mbps"), "RtsCtsThreshold", UintegerValue(0)); //RemoteStationManager:速率控制(rate control),根据网络环境选择最佳数据速率(data rate)。
devices = wifi.Install(wifiPhy, wifiMac, nodes);//将物理和Mac层设备安装到节点上并返回设备列表。
if (pcap) {
wifiPhy.EnablePcapAll(std::string("aodv")); //设置前缀名。命名规则是“前缀名-<结点标号>-<网络设备标号>”
}
}
//为节点安装协议栈,为网络设备分配IP地址
void AodvExample::InstallInternetStack() {
AodvHelper aodv;
// you can configure AODV attributes here using aodv.Set(name, value)
InternetStackHelper stack;
stack.SetRoutingHelper(aodv); // has effect on the next Install ()
stack.Install(nodes);
Ipv4AddressHelper address;
address.SetBase("10.0.0.0", "255.0.0.0"); //起始主机号默认值为0.0.0.1,address.Assign()函数会按照索引次序为容器devices中的NetDevice对象依次分配地址
interfaces = address.Assign(devices); //为设备分配网络地址,而不是为节点分配
if (printRoutes) {
Ptr<OutputStreamWrapper> routingStream = Create<OutputStreamWrapper>(
"aodv.routes", std::ios::out);
aodv.PrintRoutingTableAllAt(Seconds(8), routingStream);
}
}
//为第一个节点安装ping 应用,ping 最后一个节点
void AodvExample::InstallApplications() {
V4PingHelper ping(interfaces.GetAddress(size - 1)); //ping 最后一个节点
ping.SetAttribute("Verbose", BooleanValue(true)); //verbose方式,它要ping命令除了打印ECHO-RESPONSE数据包之外,还打印其它所有返回的ICMP数据包。
ApplicationContainer p = ping.Install(nodes.Get(0));
p.Start(Seconds(0));
p.Stop(Seconds(totalTime) - Seconds(0.001));
// move node away 移开节点
Ptr<Node> node = nodes.Get(size / 2);
Ptr<MobilityModel> mob = node->GetObject<MobilityModel>();
Simulator::Schedule(Seconds(totalTime / 3), &MobilityModel::SetPosition,
mob, Vector(-80, -10, 0));
}
代码参考自NS-3 3.35 官方src/aodv/aodv.cc,原来的源码是产生10个节点,节点排成一行,节点位置固定,节点间距50米,运行1/3 总仿真时间后将排在中间的一个节点移开。
我修改之后的代码是12个节点,每行3个,排成4行,节点位置是随时间随机移动的,同样运行1/3总仿真时间后将节点号排在中间的节点移动到Vector(-80,-10,0)的位置上。修改的主要目的很简单,就是想看看下节点排成多排,随机移动,节点按坐标点移动等运行效果。