整个仿真的目的是为了进一步研究生成结果,其中NS3提供的Tracing系统就是为了这个目的而定制的。
1.对于基本的任务,tracing系统允许用户为常用的tracing发送端生产标准的tracing,并且可以定制哪些对象生成tracing。 2.中间的用户必须能够拓展tracing系统来修改生成的输出格式,或者在不修改仿真器核心的情况下,插入新的tracing发送端。 3.高级用户可以修改仿真器核心来增加新的tracing发送端和接收端。 NS3 tracing系统是建立在独立的tracing发送端和接收端概念上,并且有统一的机制来连接发送端和接收端。Trace发送端可以在仿真过程中产生信号事件,并且提供有关数据访问通道。例如,一个trace发送端可以提供一个数据包被一个网络设备接收的时间,并且根据接收端的要求提供此数据包的内容。
Trace发送端自身是没用的,必须和接收端提供的有用信息代码段“相连”。Trace接收端是trace发送端提供的事件和时间的使用者。例如,可以创建一个可以输出数据包有用信息的trace接收端(当连接到之前例子中的trace发送端)。
这种发送端和接收端明确分工的基本原理是允许用户将已有的发送端与新类型的接收端相连,而不需要编辑和重新编译仿真器的核心。因此,上面的例子中,用户可以在他的脚本中定义一个新的tracing接收端,并且可以将其与与仿真核心中第一的tracing接收端相连。
NS3提供两种tracing机制:ASCII码tracing和pcap级别的tracing。
NS3提供了封装底层tracing系统的helper功能,用来提供配置简单数据包的更多细节。如果你使用了这个功能,将在ASCII文件中输出结果——这就是为什么这种tracing得名ASCII tracing。对于熟悉NS2的用户,这种trace与out.tr相似。
让我们在first.cc脚本中添加ASCIItracing输出。 首先,在Simulator::Run()前,添加下面的代码: AsciiTraceHelper ascii; //创建一个ASCII trace对象 pointToPoint.EnableAsciiAll (ascii.CreateFileStream(“myfirst.tr”)); //包含两个方法调用。 //CreateFileStream()用未命名的对象在协议栈中创建了一个文件流,并把这个文件流传递给了调用方法,即创建了一个对象代表着一个名为“myfirst.tr”的文件,并传递给了NS3。 //EnableAsciiAll()告诉helper你想要将ASCII tracing安装在仿真中的点到点设备上,并且你想要接收端以ASCII格式写出数据包移动信息。 这两行代码用来打开一个将被写入名为“myfirst.tr”文件中的数据流。代码段中的第二行告诉NS3在仿真中为所有点到底设备启用ASCII tracing功能,并且你想要用ASCII格式来写出数据流中数据包的移动信息。类似于NS2中,trace事件和一般的trace“+”、“-”、“d”、“r”事件。
编译并运行脚本,可以看到编译成功的信息。 此时,程序将创建一个名为“myfirst.tr”的文件。由于Waf的工作方式,这个文件将不在本地目录下创建,而是在NS3根目录中创建。
结果中的每一行对应了一个trace事件。本例中,我们查看每个点到点设备的传输队列的trace事件。传输队列是任意目的地为点到点信道的数据包必经的队列。注意!trace文件的每一行都以一个单独的字符开始(后面带有空格)。这些字符具有如下含义: 其中‘+’ :设备队列中的入队操作; ‘-’:设备队列中的出队操作; ‘d’:数据包被丢弃,通常是因为队列已满; ‘r’ :数据包被网络备接收;
我们来详细看第一行,为了看得清楚,我把这一行分为不同的部分,并在左边标出了序号: 1. +(传输队列入队操作) 2. 2.00512 (仿真时间,以s为单位) 3. /NodeList/1/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue 告诉我们哪个trace发送端发起这个事件(以tracing命名空间表示)。你可以认为tracing命名空间有点像一个文件系统命名空间。命名空间的根为NodeList。NodeList是NS3核心代码管理的一个容器,这个容器包含有一个脚本中创建的所有节点。就像文件系统在根下有目录,在NodeList下有节点数目。字符串/NodeList/1是指NodeList中的第1个节点。每个节点中有一个已经安装好的设备列表。这个列表是在命名空间的下一个出现的。可以看到trace事件来自节点中安装的第0个设备DeviceList/0。 其中$ns3::PointToPointNetDevice告诉我们第1个节点的设备列表的第0个位置的设备类型。 入队操作在最后部分的“trace path”TxQueue/Enqueue中体现。 4. ns3::PppHeader( 表明数据包封装成点到点协议) 5. Point-to-Point Protocol: IP(0x0021)) 6. ns3::Ipv4Header( 显示数据包IP版本) 7. tos 0x0 DSCP Default ECN Not-ECT ttl 63 id 0 protocol 17 offset (bytes) 0 flags [none] length: 1052 10.1.3.1 > 10.1.2.2(发送端IP地址10.1.3.1,接收端地址为10.1.2.2) 9. ns3::UdpHeader( 显示数据包的UDP头) 10. length: 1032 49153 > 9(包长1032,从端口49153到9端口) 11. Payload (size=1024) (表明数据包数据量为1024bytes)
在trace文件中的下一行显示这个数据包在这个节点中从传输队列中被移除。
NS3也支持创建.pcap格式的trace文件,缩写pcap表示packet capture,事实上是包含有定义一个.pcap文件格式的API。可以读取并且显示这种格式的程序是Wireshark。然而,有很多其他分析器也使用这个数据包格式。本例中,我们用tcpdump来查看pcap trace。 pointToPoint.EnablePcapAll (“myfirst”); 在third.cc中,我们刚增加的ASCIItrace代码后面插入这行代码。注意字符串是“myfirst”,而不是“myfirst.pcap”。这是因为这里传递的参数是个前缀,而不是完整的文件名。在仿真过程中,PointToPointHelper将为每一个点到点设备创建trace文件。文件名将包含预设前缀,节点数,设备数和”.pcap”后缀。 运行后: pcap的trace文件:first-0-0.pcap,first-1-0.pcap。 first-0-0.pcap代表第0个节点的第0个设备 用tcpdump来读pcap文件。 $ tcpdump -nn -tt -r myfirst-0-0.pcap $ tcpdump -nn -tt -r myfirst-1-0.pcap
用Wireshark读pcap文件。