ns3-manual.pdf 1.14节
上面的章节中介绍了ns3的一些重要的编程的概念。例如,保存引用计数方便内存管理的智能指针(smart pointers),属性(attributes),命名空间(namespaces),回调(callbacks)等。用户可以使用这些底层的API进行更好的粒度的编程。然而,完全是用这些底层的API编写仿真程序将会是耗时且无聊的。基于这个原因,在ns3的core包中提供了helper API。如果你阅读了ns-3 tutorial,你将会熟悉这些helper API。这些api在文件的开始就已经向用户进行了介绍。如果你感到困难,你不妨回过头去向前看这些APIs。
helper API有一些目的:
- src/文件下的其余部分并没有以来于helper API;任何使用helper API的代码都可以使用底层的API实现。
- Containers:仿真经常要对一组对象做一系列动作。helper API使得我们对一些对象容器采取相似或者不同的操作。
- helper API不是通用的;它不能最大化代码复用。因此,像拓扑机制和模板这样成功的代码服用的编程结构在这里是不适用的。例如,CsmaNetDevice helpers 和 PointToPointNetDevice helpers是分开的,并不是从NetDevice基类派生出来的。
- helper API典型用在栈分配(stack-allocated vs heap-allocated)对象空间。对于某些程序,用户不用了解底层对象的创建和处理;用户可以使用对象容器和栈分配helpers来处理。
helper API使得ns-3编程简单书写和阅读,不用花费精力在底层的接口上。章节的其他部分会提供helper API的代码实例说明helper API的方便之处。
ns-3-tutorial.pdf 4.15节 Topology Helpers
CONCEPTUAL OVERVIEW
4.15节 Topology Helpers
在现实网络中,你会发现主机被添加或者创建在NICs( network interface controller)中。在ns3中你可能会这么处理,找到node,并依附于NetDevices。在一个大型的网络仿真中,你需要安排许多在Nodes,NetDevices和Channels之间的连接。
由于连接NetDevices到Nodes,NetDevices到Channels,需要分配IP地址等,这些工作在ns-3中是普遍的任务,因此我们提供了topology helpers来帮助我们,使得尽可能简单的帮助处理这些任务。例如,创建NetDevice,添加MAC地址,安装到一些Node的NetDevice上,配置node的协议栈,然后连接NetDevice到Channel等需要使用许多不同的ns-3 core包中的操作。甚至,许多操作需要连接不同的设备到不同的信道,然后连接个人网到因特网等。我们提供topology helper对象结合这些不同的操作,抽象成简单的模型,方便用户。
ns-3-tutorial.pdf 8.3 GnuplotHelper
8.3 GnuplotHelper
在ns3中,GnuplotHelper致力于尽量少的代码产生gnuplot图。它与ns3的trace source挂钩,trace source保存数据收集系统支持的数据类型。并不是所有的ns3 trace source的数据类型都是支持的。但是许多常见的数据类型例如 TraceValues with plain old data(POD)类型都是支持的。
看看这个helper类输出的文件:
seventh-packet-byte-count.dat
seventh-packet-byte-count.plt
seventh-packet-byte-count.sh
第一个文件是以空格分割的格式化文件,包含时间戳和包的字节数。
第二个文件是gnuplot plot文件,可以用gnuplot打开。知道gnuplot的用户应该懂得,gnuplot打开上面的文件之后会生成一个sever-packet-byte-count.png文件。
第三个脚本文件会运行这个plot文件生成PNG文件,可以使用图片阅读器打开。命令如下:
sh seventh-packet-byte-count.sh
将会生成一个sever-packet-byte-count.png文件。
为什么不首先就生成这个png文件呢?
答案是,通过提供这个plt文件,用户可以在生成PNG文件前,手动配置预期的结果。
这个PNG文件的标题是“Packet Byte Count vs. Time”,探测数据来自trace source path:
/NodeList/*/$ns3::Ipv6L3Protocol/Tx
NOTE:注意路径中的通配符。总之,这个plot所捕获的packet字节来自Ipv6L3Protocol对象所传输的trace source,一方是大的596字节的TCP分片,另一个是60字节的TCP ack。(两个节点的trace sources匹配在同一个trace source)。
这是如何配置的呢?一些状态已经被设置,首先,GnuplotHelper必须声明和配置:
// Use GnuplotHelper to plot the packet byte count over time
GnuplotHelper plotHelper;
// Configure the plot. The first argument is the file name prefix
// for the output files generated. The second, third, and fourth
// arguments are, respectively, the plot title, x-axis, and y-axis labels
plotHelper.ConfigurePlot ("seventh-packet-byte-count",
"Packet Byte Count vs. Time",
"Time (Seconds)",
"Packet Byte Count");
对于这一点,一个空的plot应该被配置。文件明前缀是第一个参数。
第二个参数是plot标题。
x-axis(x轴)标签是第三个参数,
y-axis(y轴)标签是第四个参数。
下一步是配置数据,也就是在这里trace source被挂钩。首先,注意上面我们所生明的变量,稍候我们会用到:
std::string probeType;
std::string tracePath;
probeType = "ns3::Ipv6PacketProbe";
tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
我们在这里使用它们:
// Specify the probe type, trace source path (in configuration namespace), and
// probe output trace source ("OutputBytes") to plot. The fourth argument
// specifies the name of the data series label on the plot. The last
// argument formats the plot by specifying where the key should be placed.
plotHelper.PlotProbe (probeType,
tracePath,
"OutputBytes",
"Packet Byte Count",
GnuplotAggregator::KEY_BELOW);
第一个参数是probe type的名字,
第二个参数是trace source path。
当你尝试使用该框架时,这两个参数应该是最难决定的。这里的探测轨迹(trace probe)是Ipv6L3Protocol的Tx trace source。当我们查看这个类的实现代码(src/internet/model/ipv6-l3-protocol.cc)是会发现下面的代码:
.AddTraceSource ("Tx", "Send IPv6 packet to outgoing interface.",
MakeTraceSourceAccessor (&Ipv6L3Protocol::m_txTrace))
这就表明Tx是变量m_txTrace的名字,该变量有如下的声明:
/**
* \brief Callback to trace TX (transmission) packets.
*/
TracedCallback<Ptr<const Packet>, Ptr<Ipv6>, uint32_t> m_txTrace;
这表明了具体的trace source 签名是被Ipv6PacketProbe类的Probe类所支持的。参见文件:src/internet/model/ipv6-packet-probe.{h,cc}.
因此,在PlotProbe的上面的声明中,我们了解到trace source与ns3中的Ipv6PacketProbe的Probe类型挂钩。如果我们不支持这个probe 类型(也就是trace source的签名),我们就不能使用(尽管一些复杂的底层的声明可以被使用,正如手册中描述的那样)。
Ipv6PacketProbe输出包括它自己在内的trace source,以提出探测的包对象的数据:
TypeId
Ipv6PacketProbe::GetTypeId ()
{
static TypeId tid = TypeId ("ns3::Ipv6PacketProbe")
.SetParent<Probe> ()
.SetGroupName ("Stats")
.AddConstructor<Ipv6PacketProbe> ()
.AddTraceSource ( "Output",
"The packet plus its IPv6 object and interface that serve as the output for thi
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_output))
.AddTraceSource ( "OutputBytes",
"The number of bytes in the packet",
MakeTraceSourceAccessor (&Ipv6PacketProbe::m_outputBytes))
;
return tid;
}
plotHelper.PlotProbe (probeType,
tracePath,
"OutputBytes",
"Packet Byte Count",
GnuplotAggregator::KEY_BELOW);
这几句代码的第三个参数是包的字节数的声明,特别的,“OutputBytes”就是Ipv6PacketProbe的trace source。最后,第四个参数是数据序列的所表达的意思的说明,第五个参数是gnuplot中的一些标签在底部显示。其他可选的有:NO_KEY, KEY_INSIDE, 和 KEY_ABOVE。
8.4 Supported Trace Types(所支持的轨迹类型)
下面就是Probe所支持的轨迹值类型(traced values):
TracedValue type Probe type File
double DoubleProbe stats/model/double-probe.h
uint8_t Uinteger8Probe stats/model/uinteger-8-probe.h
uint16_t Uinteger16Probe stats/model/uinteger-16-probe.h
uint32_t Uinteger32Probe stats/model/uinteger-32-probe.h
bool BooleanProbe stats/model/uinteger-16-probe.h
ns3::Time TimeProbe stats/model/time-probe.h
下面是Probes所支持的TraceSource 类型:
TracedSource type Probe type Probe outputs File
Ptr<const Packet> PacketProbe Output-Bytes network/utils/packet-probe.h
Ptr<const Packet>, Ipv4PacketProbe Output-Bytes internet/model/ipv4-packet-probe.h
Ptr<Ipv4>, uint32_t
Ptr<const Packet>, Ipv6PacketProbe Output-Bytes internet/model/ipv6-packet-probe.h
Ptr<Ipv6>, uint32_t
Ptr<const Packet>, Ipv6PacketProbe Output-Bytes internet/model/ipv6-packet-probe.h
Ptr<Ipv6>, uint32_t
Ptr<const Packet>, ApplicationPack-etProbe Output-Bytes applications/model/application-packet-probe.h
const Address&
正如我们所看到的,只有一些轨迹源(trace source)是支持的。它们都导向到输出字节的大小。然而,大多基础的数据类型如TracedValues是被这些helper类所支持的。
ns-3-tutorial.pdf 8.5 FileHelper
8.5 FileHelper
FileHelper类是GnuplotHelper类的变异。例子程序提供了时间戳数据的格式化输出,如下:
Time (Seconds) = 9.312e+00 Packet Byte Count = 596
Time (Seconds) = 9.312e+00 Packet Byte Count = 564
提供了两个文件,一个是节点0,一个是节点1,这从文件命名就可以看出。下面从代码中一行行看:
// Use FileHelper to write out the packet byte count over time
FileHelper fileHelper;
// Configure the file to be written, and the formatting of output data.
fileHelper.ConfigureFile ("seventh-packet-byte-count",
FileAggregator::FORMATTED);
文件命名的前缀是第一个参数,特定的格式是第二个参数。其他的像SPACE_SEPARATED(空格), COMMA_SEPARATED(逗号), and TAB_SEPARATED(制表符)分割的格式是可选的。用户可以像下面的代码一样来控制格式化:
// Set the labels for this formatted output file.
fileHelper.Set2dFormat ("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");
最后,用户所感兴趣的跟踪信息(trace source)一定要挂钩。在这个例子中的probeType and tracePath俩个变量是使用的,探测的输出trace source “OutputBytes”是挂钩的。(翻译之后,不知道说的什么,直接粘贴以下:Finally, the trace source of interest must be hooked. Again, the probeType and tracePath variables in this example are
used, and the probe’s output trace source “OutputBytes” is hooked:)
// Specify the probe type, trace source path (in configuration namespace), and
// probe output trace source ("OutputBytes") to write.
fileHelper.WriteProbe (probeType,
tracePath,
"OutputBytes");
在tarce source中的通配符会匹配两个trace sources。在GnuplotHelper中,两个数据会加载在同一个plot中。与之不同的是,这里会使用写入磁盘的两个文件中。