NS-3学习笔记 5

说明:今天学习《ns-3 tutorial》第7章 Tracing。

7. Tracing

7.1 Background

运行NS-3模拟的落脚点是得到运行结果的输出,而获得输出有两类基本方法:1.使用通用的预定义的大量输出方法并解析输出内容,以获取感兴趣的信息;2.开发新的输出机制来获取感兴趣的信息。
方法1的好处是不需要改变ns3,但要求编写脚本解析和过滤兴趣数据,通常在脚本运行时,可以PCAP或NS_LOG形式输出的信息,可以利用grep,sed或awk等linux工具解析信息,减少无用数据和转化数据格式。NS_LOG不是NS-3API的一部分,它可能在不同版本中表现不一样,而且NS_LOG仅能在debug builds时获得,所以会影响模拟程序的运行性能。

NS3提供了Tracing机制来避免其他内置输出方式的各种问题。使用Tracing机制来得到输出,有几个优势:

  • 可以通过跟踪较少的事件来减少输出数据
  • 可以直接控制输出格式,不再需要其他脚本工具来整理数据
  • 可以在内核中增加钩子
    NS3官方手册认为ns-3的tracing系统是获得模拟输出的最佳机制,也是在学NS3时需要重点理解的内容。

7.1.1 钝器(Blunt Instruments)

最简单的获得数据输出的方法是使用标准输出cout或print方法:

void
SomeFunction(void)
{
    uinit32_t x = SOME_INTERESTING_VALUE;
    ...
    std::cout << "The value of x is " << x << std::endl;
}

但在大型模拟程序中,类似输出语句的增多会使的程序越来越复杂。最后你可能会发现自己在重新实现NS_LOG模块的种种功能。
在使用NS-LOG时,如果发现一些信息无法得到,你可以改变源代码,追加NS_LOG输出,例如原始的TcpSocketBase中并不记录在ESTABLISHED状态时的SYN+ACK包,源代码如下:

void
TcpSocketBase::ProcessEstablished(Ptr<Packet> packet, const TcpHeader& tcpHeader)
{
    NS_LOG_FUNCTION(this << tcpHeader);
    ...
    else if(tcpflags == (TcpHeader::SYN || TcpHeader::ACK)
    {
        //不记录
    }
    ...
}

为了使用NS_LOG输出这类数据包,你可以改变源代码的相应部分:

void
TcpSocketBase::ProcessEstablished(Ptr<Packet> packet, const TcpHeader& tcpHeader)
{
    NS_LOG_FUNCTION(this << tcpHeader);
    ...
    else if(tcpflags == (TcpHeader::SYN || TcpHeader::ACK)
    {
        //记录
        NS_LOG_LOGIC("TcpSocketBase" << this << " ignoring SYN+ACK");
    }
    ...
}

上面的方法虽然可以解决一些问题,但不是最好的方法。理想的方法是使用API访问核心系统,仅获取所需信息,且不改变原始的NS3源代码。

7.2 Overview

ns-3的tracing系统建立在跟踪source与跟踪sink相互独立的概念上,并且采用了统一的机制来连接source与sink。source是那些在模拟过程中能够向事件发出信号的并且能够访问相关兴趣数据的实体。例如,一个trace source能够指出何时某个网络设备接收到了一个包,并且向trace sink提供对这个包内容的访问接口。一个trace source能够指出何时模型的状态发生变化。例如tcp的协调窗口就可以作为一个trace source,当窗口大小发生变化时,可以将变化前、后的值都传给trace sink。只有trace source自己产生信息是没有意义的,必须有消费者。
trace sink就是trace source信息的消费者。
ns3中Trace source与Trace sink间这种清晰的划分允许大量的source散落在系统或模型中,凡是模型的作者认为有需要的地方都可以设置source,而插入trace source带来的执行代价是很小的。
每个trace source产生的跟踪事件可以有0个或多个消费者,可以将它们看成是1对多的关系,消费同一trace source消息的不同的trace sink之间不会有任何相互影响。这保证了脚本编写时的独立性和简易性。
Trace source与sink间必须通过一种规范的机制连接起来,否则不会有任何输出。

7.2.1 简单例子

下面看一个简单的tracing例子,这可能需要一些callback知识才能理解,所以先说一下callback。
1.callbacks
在NS-3中,回调系统的目的是使得一段代码可以在没有任何特别的模块间依赖的情况下调用一个函数。这意味着你需要某种间接的方式调用函数——使用函数的地址调用。事实上trace sink就是某个callback。
一个trace sink想消费某个源事件产生的消息时,它可以把自己作为一个callback添加到由trace source控制的callbacks列表中。当相关兴趣事件发生时,source就调用operator()方法,并传给该方法以0个~多个参数,这些参数就是sink函数的指针,通过指针间接调用sink函数。对于这个问题,更多的细节可以参考《ns-3 Manual》。
2. 过一遍fourth.cc
ns3目录下的examples/tutorial/fourth.cc中是一个简单的tracing例子:

#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
  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值