ns3中first.cc~fourth.cc代码注释
参考博客:
ubuntu 18.04安装NS-3教程(详细安装过程)
ns-3脚本初识——点对点有线网络:first脚本
ns-3中的数据跟踪与采集——Tracing系统综述及fourth脚本
-------------------------------------------------------------------------------------------
大概的架构如上所示。主要分为三个部分,Node、NetDevice、Channel和Application。
1、Node可以看做是可以添加各种功能的计算机;由 C++中的 Node 类来描述。Node类提供了用于管理仿真器中网络组件表示的各种方法。
2、NetDevice相当与网卡+软件驱动,NS3中,NetDevice相当于安装在节点上,使得节点通过信道和其他节点通信。像真实的计算机一样,一个节点可以通过多个网络设备同时连接到多条信道上。由 C++中的 NetDevice 类来描述。 NetDevice 类提供了管理连接其他节点和信道对象的各种方法,并且允许开发者以面向对象的方法来自定义。这几个例子中主要使用是 CsmaNetDevice、PointToPointNetDevice, 和 WifiNetDevice。CsmaNetDevice 被设计成在 csma 信道中工作,而PointToPointNetDevice 在 PointToPoint 信道中工作,WifiNetNevice 在 wifi 信道中工作。
3、Channel把节点连接到代表数据交换信道的对象上,在 C++中用 Channel 类来描述。Channel 类提供了管理通信子网对象和把节点连接至它们的各种方法。信道类同样可以由开发者以面向对象的方法自定义。一个信道实例可以模拟一条简单的线缆(wire),也可以模拟一个复杂的巨型以太网交换机,甚至无线网络中充满障碍物的三维空间。实例中使用的:CsmaChannel,
PointToPointChannel 和 WifiChannel。举例来说,CsmaChannel 信道模拟了用于一个可以实现载波侦听多路访问通信子网中的媒介。这个信道具有和以太网相似的功能。
4、ns-3 中,需要被仿真的用户程序被抽象为应用。应用在 C++中用 Application类来描述。这个类提供了管理仿真时用户层应用的各种方法。开发者应当用面向对象的方法自定义和创建新的应用。在本教程中,我们会使用 Application 类的实例: UdpEchoClientApplication 和 UdpEchoServerApplication。也许你已经猜到了,这些应用程序包含了一个 client/server 应用来发送和回应仿真网络中的数据包。
------------------------------------------------------------------------------------------
first.cc
1、Ns3 Namespace
Ns-3 工程是在一个叫做 ns3 的 C++ 命名空间中实现的。这把所有与 ns3 相关的声明,集中在一个与全局命名空间相区别的命名空间中。我们希望这样会给ns3 与其他代码的集成带来好处。 C++用“using ”语句来把 ns-3 namespace引入到当前的(全局的)声明域中。这个声明就是说,你不用为了使用 ns-3 的代码而必须在所有的 ns-3 代码前打上 ns3:: 作用域操作符。
2、logging
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");声明了一个叫 FirstScriptExample 的日志构件,通过引用 FirstScriptExample 这个名字的操作,可以实现打开或者关闭控制台日志的输出。
3、mian
下面两行脚本是用来使两个日志组件生效的。它们被内建在 Echo Client 和Echo Server 应用中:
LogComponentEnable("UdpEchoClientApplication",LOG_LEVEL_INFO);
LogComponentEnable("UdpEchoServerApplication", LOG_LEVEL_INFO);
如果你已经读过了日志组件文档,你会看到日志分成一系列详尽级别。这两行代码将回显 clients 和 server 的日志级别设为”INFO”级。这样,当仿真发生数据包发送和接受时,对应的应用就会输出相应的日志消息
4、NodeContainer
NodeContainer nodes;
nodes.Create (2);
节点代表一台能够加入诸如协议栈,应用以及外设卡等等的东西的计算机。NodeContainer 的拓扑生成器提供一种简便的方式来创建、管理和使用任何节点对象,我们用这些节点来运行模拟器。上面的第一行只是声明了一个名为”nodes”的NodeContainer。第二行调用了 nodes 对象的 Create()方法创建了两个节点。
5、PointToPointHelper
使用 PointToPointHelper 来配置和连接 ns-3 的PointToPointNetDevice 和 PointToPointChannel 对象。
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
其中第一行,PointToPointHelper pointToPoint;在栈中初始化了一个 PointToPointHelper 的对象 PointToPoint。而紧接着的下一行,pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));从上层的角度告诉 PointToPointHelper 对象当创建一个 PointToPointNetDevice 对象时使用“5Mbps"来作为数据速率。
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));告诉 PointToPointHelper 使用"2ms"(2 毫秒)作为每一个被创建的点到点信道传输延时值。
6、NetDeviceContainer
我们使用 NodeContainer 拓扑生成器对象来为我们的模拟创建节点,我们会让 PointToPointHelper 来做关于创建,配置和安装设备的工作。我们需要一个所有被创建的 NetDevice 对象列表,所以我们使用一个NetDeviceContainer 对象来存放它们,就像我们使用一个 NodeContainer 对象来存放我们所创建节点。下面两行代码:
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
会完成设备和信道的配置。第一行声明了上面提到的设备容器,第二行完成了主要工作。PointToPointHelper 的 Install()方法以一个 NodeContainer 对象作为一个参数。在 Install()方法内,一个 NetDeviceContainer 被创建了。对于在NodeContainer 对象中的每一个节点(对于一个点到点链路必须明确有两个节点),一个 PointToPointNetDevice 被创建和保存在设备容器内。一个PointToPointChannel 对象被创建,两个 PointToPointNetDevices 与之连接。当PointToPointHelper 对象创建时,那些在生成器中就被预先地设置的属性被用来初始化对象对应的属性值。当调用了 pointToPoint.Install(nodes)后,我们会有两个节点,每一个节点安装了点到点网络设备,在它们之间是一个点到点信道。两个设备会被配置在一个有 2毫秒传输延时的信道上以 5M 比特每秒的速率传输数据。
7、InternetStackHelper
我们现在已经配置了节点和设备,但是我们还没有在节点上安装任何协议栈。下面两行代码完成这个任务:
InternetStackHelper stack;
stack.Install (nodes);
类 InternetStackHelper 是一个安装 PointToPointHelper 对象和点到点网络设备的网络协议栈的拓扑生成器类。其中 Install()方法以一个 NodeContainer 对象做为一个参数,当它被执行后,它会为每一个节点容器中的节点安装一个网络协议栈
(TCP,UDP,IP 等等)。
8、Ipv4AddressHelper
下面我们需要为节点上的设备设置 IP 地址。我们也提供了一个拓扑生成器来管理 IP 地址的分配。当执行实际的地址分配时唯一用户可见的 API 是设置基 IP 地址和子网掩码。在我们的范例脚本文件 first.cc 的下两行代码
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
声明了一个地址生成器对象,并且告诉它应该开始从 10.1.1.0 开始以子网掩码为255.255.255.0 分配地址。地址分配默认是从 1 开始并单调的增长,所以在这个基础上第一个分配的地址会是 10.1.1.1,紧跟着是 10.1.1.2 等等。底层 ns-3 系统事实上会记住所有分配的 IP 地址,如果你无意导致了相同 IP 地址的产生,这将是一个致命的错误(顺便说一下,这是个很难调试正确的错误)。下面一行代码,完成了真正的地址配置。在 ns-3 中我们使用 Ipv4Interface 对象将一个 IP 地址同一个设备关联起来。正如我们有时候需要一个被生成器创建的网络设备列表一样,我们有时候需要一个 Ipv4Interface 对象的列表。Ipv4InterfaceContainer 提供了这样的功能。
Ipv4InterfaceContainer interfaces = address.Assign (devices);
现在我们有了一个安装了协议栈,配置了 IP 地址类的点到点的网络。这时我们所要做的事情是运用它来产生数据通信。
9、Applications
另一个 ns-3 系统的核心抽象是 Application 类。在这个脚本中我们用两个特定的ns-3 核心 Application 类: UdpEchoServerApplication 和 UdpEchoClientApplication。正如我们先前声明过的一样,我们使用生成器对象来帮助配置和管理潜在的对象。在这里,我们用 UdpEchoServerHelper 和 UdpEchoClientHelper 对象使我们的工作更加容易点。
(1)、UdpEchoServerHelper
下面在 first.cc 脚本中的代码被用来在我们之前创建的节点上设置一个 UDP 回显服务应用。
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
上面一片代码中的第一行声明了 UdpEchoServerHelper。 像往常一样,这个并非应用本身,这是一个用来帮助创建真正应用的对象。我们约定在生成器中放置必需的属性。本例中,除非我们告知生成器服务器和客户端所共 知的一个端口号,否则这个生成器是不会起任何作用的。我们并没有随机选择,而是把这个端口号作为生成器构造函数的一个参数。只要你愿意,你就能够使用 SetAttribute 设置“Port”参数到另一个值。
同其它生成器对象类似,UdpEchoServerHelper 对象有一个 Install 方法。实际上是这个方法的执行,才初始化回显服务器的应用,并将应用连接到一个节点上去。有趣的是,安装方法把 NodeContainter 当做一个参数,正如我们看到的其他安装方法一样。这里有一个 C++隐式转换,此转换以 nodes.Get(1)的结果作为输入,并把它作为一个未命名的 NodeContainer 的构造函数的参数,最终这个未命名的NodeContainer 被送入 Install 方法中去。我们现在会看到 echoServer.Install 将会在管理节点的 NodeContainer 容器索引号为 1 的机节点上安装一个 UdpEchoServerApplication。安装会返回一个容器,这个容器中包含了指向所有被生成器创建的应用指针。
应用对象需要一个时间参数来“开始”产生数据通信并且可能在一个可选的时间点“停止”。我们提供了开始和停止的两个参数。这些时间点是用ApplicationContainer 的方法 Start 和 Stop 来设置的。
(2)UdpEchoClientHelper
echo 客户端应用的设置与回显服务器端类似。也有一个 UdpEchoClientHelper 来管理 UdpEchoClientApplication。然而对于 echo 客户端,我们需要设置五个不同的属性。首先两个属性是在UdpEchoClientHelper 的构建过程中被设置的。按照生成器的构造函数的格式,我们把”RemoteAdress”和”RemotePort”属性传递给了生成器(实际上是作为生成器构造函数的两个必须参数传递的)。
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
回忆一下我们使用 Ipv4InterfaceContainer 来追踪我们配置给设备的 IP 地址。在界面容器中位置零的界面对象将会和在节点容器中的位置零的节点对象对应。同样在界面容器中位置一的界面对象将会和在节点容器中的位置一的节点对象对应。所以,在上面的第一行代码中,我们创建了一个生成器并告诉它设置客户端的远端地址为服务器节点的 IP 地址。我们同样告诉它准备发送第二个数据包到端口 9。
那个“MaxPackets”属性告诉客户端我们所允许它在模拟期间所能发送的最大数据包个数。“Interval”属性告诉客户端在两个数据包之间要等待多长时间,而“PacketSize”属性告诉客户端它的数据包应该承载多少数据。本例中,我们让客户端发送一个 1024 字节的数据包。正如 echo 服务端一样,我们告诉 echo 客户端何时来开始和停止,但是这里我们使客户端在服务端生效 1s 后才开始(在模拟器中时间 2s 的时候)
10、Simulator
运行模拟器,这是用全局函数 Simulator::Run.来做到的Simulator::Run ();
serverApps.Start (Seconds (1.0));serverApps.Stop (Seconds (10.0));
clientApps.Start (Seconds (2.0));clientApps.Stop (Seconds (10.0));
实际上我们是在模拟器中 1.0 秒,2.0 秒,和 10.0 时预设了时间的发生。当Simulator::Run 被调用时,系统会开始遍历预设事件的列表并执行。首先它会在1.0s 时运行事件,这个事件会使 echo 服务端应用生效(这个事件会预设更多的其他事件)。接下来仿真器会运行在 t=2.0 秒时的事件,即让 echo 客户端应用开始。同样的,这个事件可能会预定更多的其他事件。在 echo 客户端应用中的开始事件的执行会通过给服务端传送一个数据包来开始仿真的数据传送阶段。发送一个数据包给服务端会引发一系列更多的事件。这些事件会被预设在此事件之后,并根据我们已经在脚本中设定的时间参数来执行数据包的应答。
其实,我们只发送了一个数据包(回忆一 MaxPackets 属性被设置为一),在此之后,那个被单独的客户端应答请求所引发的连锁反应会停止,并且模拟器会进入空闲状态。当这发生时,生下来的事件就是服务端和客户端的 Stop 事件。当这些事件被执行后,就没有将来的事件来执行了,函数 Simulator::Run 会返回。整个模拟过程就结束了。
剩下的事情就是清理了。这个通过调用全局函数 Simulator::Destroy 来完成。当生成器函数(或者低级的 ns-3 代码)被执行后,生成器安排的钩子函数就被插入到模拟器中来销毁所有被创建的对象。你自己并不需要追踪任何对象,你所需要做的仅仅是调用 Simulator::Destroy 并且退出。ns-3 系统会帮你料理这些繁杂的任务。在 first.cc 脚本中剩下的代码如下: Simulator::Destroy ();
完整代码
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
//use ns3 namespace and no need to add ns3:: operator
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
int
main (int argc, char *argv[])
{
//read conmandline paramaters
CommandLine cmd;
cmd.Parse (argc, argv);
Time::SetResolution (Time::NS);//minimum time unit
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);//log component and log level
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
//node--netdevice --------------channel-----------------netdevice--node
//NetDevice----link layer Channel----physical layer
//in the example,netdevice is PointToPointNetDevice,channel is PointToPointChannel.
//Node(computer)
NodeContainer nodes;
nodes.Create (2);
//set channel parematers
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//create channel , link node and channel
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
//install TCP/IP for node
InternetStackHelper stack;
stack.Install (nodes);
//distribute net address for devices
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
//application
//set port to listenning (server)
UdpEchoServerHelper echoServer (9);
//create srever at node 1 , start then receive or send the package
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
//set the server address and port to send package
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
//set the client paramaters
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
//create client at node 0 and start
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
//simulator start and destroy
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
------------------------------------------------------------------------
seconds.cc
下面是csma网络,上面是p2p,csma需要另外配置,见注释 .或参考博客:点我
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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/core-module.h"
#include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/ipv4-global-routing-helper.h"
// Default Network Topology
//
// 10.1.1.0
// n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// ================
// LAN 10.1.2.0
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("SecondScriptExample");
int
main (int argc, char *argv[])
{
bool verbose = true;
uint32_t nCsma = 3;
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
cmd.Parse (argc,argv);
if (verbose)
{
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
//the number of csma node
nCsma = nCsma == 0 ? 1 : nCsma;
NodeContainer p2pNodes;
p2pNodes.Create (2);
NodeContainer csmaNodes;
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);
//PPP parematers
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
//csma parematers
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
//install the tcp/ip on node 0 and cama nodes(node 1 within)
InternetStackHelper stack;
stack.Install (p2pNodes.Get (0));
stack.Install (csmaNodes);
//distribute the address for ppp and csma
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);
address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
//create server(csma)
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
//create client node 0
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (p2pNodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
//open the pcap to catch the packet
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
pointToPoint.EnablePcapAll ("second");
csma.EnablePcap ("second", csmaDevices.Get (1), true);
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
--------------------------------------------------------------------
third.cc
要配置WiFi和cams和p2p 。具体看代码注释,或参考博客:点我
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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/core-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
// Default Network Topology
//
// Wifi 10.1.3.0
// AP
// * * * *
// | | | | 10.1.1.0
// n5 n6 n7 n0 -------------- n1 n2 n3 n4
// point-to-point | | | |
// ================
// LAN 10.1.2.0
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("ThirdScriptExample");
int
main (int argc, char *argv[])
{
bool verbose = true;
uint32_t nCsma = 3;
uint32_t nWifi = 3;
bool tracing = false;
CommandLine cmd;
cmd.AddValue ("nCsma", "Number of \"extra\" CSMA nodes/devices", nCsma);
cmd.AddValue ("nWifi", "Number of wifi STA devices", nWifi);
cmd.AddValue ("verbose", "Tell echo applications to log if true", verbose);
cmd.AddValue ("tracing", "Enable pcap tracing", tracing);
cmd.Parse (argc,argv);
// The underlying restriction of 18 is due to the grid position
// allocator's configuration; the grid layout will exceed the
// bounding box if more than 18 nodes are provided.
if (nWifi > 18)
{
std::cout << "nWifi should be 18 or less; otherwise grid layout exceeds the bounding box" << std::endl;
return 1;
}
if (verbose)
{
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
}
NodeContainer p2pNodes;
p2pNodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
//connect the channel with node
NetDeviceContainer p2pDevices;
p2pDevices = pointToPoint.Install (p2pNodes);
//csma add node 1
NodeContainer csmaNodes;
//create ncsma
csmaNodes.Add (p2pNodes.Get (1));
csmaNodes.Create (nCsma);
//set paramaters
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue ("100Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (NanoSeconds (6560)));
//install csma nodes
NetDeviceContainer csmaDevices;
csmaDevices = csma.Install (csmaNodes);
//create wifi nodes
NodeContainer wifiStaNodes;
wifiStaNodes.Create (nWifi);
NodeContainer wifiApNode = p2pNodes.Get (0);
//phy setting
YansWifiChannelHelper channel = YansWifiChannelHelper::Default ();
YansWifiPhyHelper phy = YansWifiPhyHelper::Default ();
phy.SetChannel (channel.Create ());
WifiHelper wifi;
wifi.SetRemoteStationManager ("ns3::AarfWifiManager");
//mac wifi node
WifiMacHelper mac;
Ssid ssid = Ssid ("ns-3-ssid");
mac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid),
"ActiveProbing", BooleanValue (false));
NetDeviceContainer staDevices;
staDevices = wifi.Install (phy, mac, wifiStaNodes);
//wifi ap node
mac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));
NetDeviceContainer apDevices;
apDevices = wifi.Install (phy, mac, wifiApNode);
//mobile model(wifi:normal node,ap node)
MobilityHelper mobility;
mobility.SetPositionAllocator ("ns3::GridPositionAllocator",
"MinX", DoubleValue (0.0),
"MinY", DoubleValue (0.0),
"DeltaX", DoubleValue (5.0),
"DeltaY", DoubleValue (10.0),
"GridWidth", UintegerValue (3),
"LayoutType", StringValue ("RowFirst"));
mobility.SetMobilityModel ("ns3::RandomWalk2dMobilityModel",
"Bounds", RectangleValue (Rectangle (-50, 50, -50, 50)));
mobility.Install (wifiStaNodes);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (wifiApNode);
//set tcp/ip on csma and wifi(ap/normal)
InternetStackHelper stack;
stack.Install (csmaNodes);
stack.Install (wifiApNode);
stack.Install (wifiStaNodes);
//set ip address on p2p csma wifi(ap/normal)
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer p2pInterfaces;
p2pInterfaces = address.Assign (p2pDevices);
address.SetBase ("10.1.2.0", "255.255.255.0");
Ipv4InterfaceContainer csmaInterfaces;
csmaInterfaces = address.Assign (csmaDevices);
address.SetBase ("10.1.3.0", "255.255.255.0");
address.Assign (staDevices);
address.Assign (apDevices);
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (csmaNodes.Get (nCsma));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps =
echoClient.Install (wifiStaNodes.Get (nWifi - 1));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
//set global routing to help to build the net routing
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
Simulator::Stop (Seconds (10.0));
if (tracing == true)
{
pointToPoint.EnablePcapAll ("third");
phy.EnablePcap ("third", apDevices.Get (0));
csma.EnablePcap ("third", csmaDevices.Get (0), true);
}
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
--------------------------------------------------------------------------
fourth.cc
ns-3的跟踪与采集技术除了直接将执行过程显示在命令行中的Logging系统,还有一种更为常用的将采集到的数据直接存放在一个文件中以便后期处理与分析的Tracing系统。
ns-3的Tracing系统大体分为3个部分:Tracing Sources,Tracing Sinks,以及将Tracing Sources和Tracing Sinks关联起来的方法。
1、Tracing Sources是一个实体,它可以用来标记仿真中发生的时间,也可以提供一个访问底层数据的方法。例如,当一个网络设备或者网卡收到一个网络分组时,Tracing Sources可以指示并提供一个途经将分组的内容传递给对该分组感兴趣的Tracing Sinks。此外,Tracing Sources还可以在感兴趣的状态发生变化时给出相应的指示。例如,TCP 网络协议模块中的拥塞窗口发生改变时,Tracing Sources会给出指示。
2、Tracing Sources提供信息,而Tracing Sinks消费信息。Tracing Sources本身不起任何作用,只有当它和一段有实际功能的代码相关联时才有意义,这段代码就是使用Tracing Sources提供的信息来做相关事物的。使用(或消费)Tracing Sources提供信息的实体称为Tracing Sink。
3、一个Tracing Sources产生的信息可以没有Tracing Sink消费,也可以有一个或者多个Tracing Sink消费。它们之间是一对多的关系。
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* 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/object.h"
#include "ns3/uinteger.h"
#include "ns3/traced-value.h"
#include "ns3/trace-source-accessor.h"
#include <iostream>
using namespace ns3;
class MyObject : public Object
{
public:
/**
* Register this type.
* \return The TypeId.
*/
//TypeId is used to record the mate data of class created by object
static TypeId GetTypeId (void)
{
static TypeId tid = TypeId ("MyObject")
//relationship with parent class
.SetParent<Object> ()
.SetGroupName ("Tutorial")
//when user use the factory model ,he needn't to describe the detail,just to use it
.AddConstructor<MyObject> ()
//link the trace source "MyInteger" with outdoor
.AddTraceSource ("MyInteger",
"An integer value to trace.",
//link the m_myInt variable
MakeTraceSourceAccessor (&MyObject::m_myInt),
"ns3::TracedValueCallback::Int32")
;
return tid;
}
MyObject () {}
//the data need to be traced
TracedValue<int32_t> m_myInt;
};
//callback this function while the value of trace source changed
void
IntTrace (int32_t oldValue, int32_t newValue)
{
std::cout << "Traced " << oldValue << " to " << newValue << std::endl;
}
int
main (int argc, char *argv[])
{
Ptr<MyObject> myObject = CreateObject<MyObject> ();
//link the trace source and trace sink
myObject->TraceConnectWithoutContext ("MyInteger", MakeCallback (&IntTrace));
myObject->m_myInt = 1234;
}
上一篇: UDP简单介绍与通讯模拟(C)