c++ - FlowMonitor 不显示统计数据,但 PyViz 和跟踪文件显示它

标签 c++ network-programming ns-3

有一个简单的数据传输模型。

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include <iostream>
#include <fstream> 
#include <string>  
#include <cassert> 

#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"
#include "ns3/flow-monitor-module.h"       

//
// Network Topology
//                         
//    n0 (source)           
//    |
//    |
//    |
//    |   
//    |
//    -------------------n1      n2        n3--------n4  n5   n6 (sink)
//    point-to-point      |      |         |         |   |    |
//     10.1.1.0           ==================         ==========
//                        LAN 10.1.2.0              LAN 10.1.3.0  
//                      (CSMA subnet 1)           (CSMA subnet 2)    

using namespace ns3;

int main (int argc, char *argv[])
{                       
        Config::SetDefault ( "ns3::OnOffApplication::PacketSize", UintegerValue ( 700 ) );
        Config::SetDefault ( "ns3::OnOffApplication::DataRate", StringValue ( "1000000" ) );

        CommandLine cmd;
        cmd.Parse(argc,argv);

        NodeContainer p2pNodes;
        p2pNodes.Create(2);   

        NodeContainer csmaNodesSubNetOne;
        csmaNodesSubNetOne.Add(p2pNodes.Get(1));
        csmaNodesSubNetOne.Create(2);        

        NodeContainer csmaNodesSubNetTwo;
        csmaNodesSubNetTwo.Add(csmaNodesSubNetOne.Get(2));
        csmaNodesSubNetTwo.Create(2);

        PointToPointHelper pointToPoint;
        pointToPoint.SetDeviceAttribute("DataRate", StringValue ("100Mbps"));
        pointToPoint.SetDeviceAttribute("Mtu", UintegerValue(1000));        
        pointToPoint.SetChannelAttribute("Delay", TimeValue (NanoSeconds (6560)));    

        NetDeviceContainer p2pDevices;
        p2pDevices = pointToPoint.Install(p2pNodes);

        CsmaHelper csmaHelperSubNetOne;
        csmaHelperSubNetOne.SetChannelAttribute("DataRate", StringValue ("100Mbps"));
        csmaHelperSubNetOne.SetChannelAttribute("Delay", TimeValue (NanoSeconds (6560)));
        csmaHelperSubNetOne.SetDeviceAttribute("Mtu", UintegerValue(1000));               

        NetDeviceContainer csmaDevicesSubNetOne;
        csmaDevicesSubNetOne = csmaHelperSubNetOne.Install(csmaNodesSubNetOne);

        CsmaHelper csmaHelperSubNetTwo;
        csmaHelperSubNetTwo.SetChannelAttribute("DataRate", StringValue ("100Mbps"));
        csmaHelperSubNetTwo.SetChannelAttribute("Delay", TimeValue (NanoSeconds (6560)));
        csmaHelperSubNetTwo.SetDeviceAttribute("Mtu", UintegerValue(1000));               

        NetDeviceContainer csmaDevicesSubNetTwo;
        csmaDevicesSubNetTwo = csmaHelperSubNetTwo.Install(csmaNodesSubNetTwo);

        InternetStackHelper internetStackHelper;
        internetStackHelper.Install(p2pNodes.Get(0));

        internetStackHelper.Install(csmaNodesSubNetOne.Get(0));
        internetStackHelper.Install(csmaNodesSubNetOne.Get(1));

        internetStackHelper.Install(csmaNodesSubNetTwo.Get(0));
        internetStackHelper.Install(csmaNodesSubNetTwo.Get(1));
        internetStackHelper.Install(csmaNodesSubNetTwo.Get(2));

        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 csmaInterfacesSubNetOne;
        csmaInterfacesSubNetOne = address.Assign (csmaDevicesSubNetOne);

        address.SetBase ("10.1.3.0", "255.255.255.0");
        Ipv4InterfaceContainer csmaInterfacesSubNetTwo;
        csmaInterfacesSubNetTwo = address.Assign (csmaDevicesSubNetTwo);

        InetSocketAddress dst = InetSocketAddress ( csmaInterfacesSubNetTwo.GetAddress ( 2 ) );
        OnOffHelper onoff = OnOffHelper ( "ns3::Ipv4RawSocketFactory", dst );

        ApplicationContainer apps = onoff.Install( p2pNodes.Get(0) );
        apps.Start ( Seconds (2.0) );
        apps.Stop ( Seconds (10.0) );

        PacketSinkHelper sink = PacketSinkHelper ("ns3::Ipv4RawSocketFactory", dst);
        apps = sink.Install (csmaNodesSubNetTwo.Get( 2 ));
        apps.Start (Seconds (1.0));
        apps.Stop (Seconds (10.0));

        Ipv4GlobalRoutingHelper::PopulateRoutingTables( );  

        csmaHelperSubNetTwo.EnablePcap ("sniffer", csmaDevicesSubNetTwo.Get (1), true);

        AsciiTraceHelper ascii;
        csmaHelperSubNetTwo.EnableAsciiAll( ascii.CreateFileStream( "receiver-trace.tr" ) );

        Simulator::Stop (Seconds (11));

        FlowMonitorHelper flowmon;
        Ptr<FlowMonitor> monitor = flowmon.InstallAll();
        monitor = flowmon.GetMonitor();

        Simulator::Run ();

        monitor->CheckForLostPackets ();
        Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmon.GetClassifier ());
        std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();
        for(std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin (); i != stats.end (); ++i)
        {
                Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);

                std::cout << "  Flow " << i->first << " (" << t.sourceAddress << " -> " << t.destinationAddress << ")\n";
                std::cout << "  Tx Bytes:   " << i->second.txBytes << "\n";
                std::cout << "  Rx Bytes:   " << i->second.rxBytes << "\n";
                std::cout << "  Throughput: " << i->second.rxBytes * 8.0 / 10.0 / 1024 / 1024  << " Mbps\n";
        }

        monitor->SerializeToXmlFile("serialize-stat.flowmon", true, true);

        Simulator::Destroy();
        return 0;
}

我可以构建并运行此模型并在 PyViz 中查看结果.

enter image description here

我还在 PyViz 中看到节点接收器的统计信息。

enter image description here

跟踪文件包含数据。这是大跟踪文件中的一行。

...
r 3.00585 /NodeList/5/DeviceList/0/$ns3::CsmaNetDevice/MacRx ns3::EthernetHeader ( length/type=0x800, source=00:00:00:00:00:06, destination=00:00:00:00:00:08) ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 0 protocol 0 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700) ns3::EthernetTrailer (fcs=0)
...

我可以使用 AWK 解析这个跟踪文件.

[root@localhost ns-3.16]# awk '{print $2 ", " $28}' receiver-trace.tr >grab.dat
[root@localhost ns-3.16]# cat grab.dat
...
3.00578, 720
3.00578, 720
3.00585, 720
3.01126, 720
3.01126, 720
3.01133, 720
3.01133, 720
3.01133, 720
3.0114, 720
3.01686, 720
3.01686, 720
3.01693, 720
3.01693, 720
3.01693, 720
3.017, 720
3.02246, 720
...

但是FlowMonitor什么都没有显示,xml 文件没有有用的信息。

<?xml version="1.0" ?>
<FlowMonitor>
  <FlowStats>
  </FlowStats>
  <Ipv4FlowClassifier>
  </Ipv4FlowClassifier>
  <FlowProbes>
    <FlowProbe index="0">
    </FlowProbe>
    <FlowProbe index="1">
    </FlowProbe>
    <FlowProbe index="2">
    </FlowProbe>
    <FlowProbe index="3">
    </FlowProbe>
    <FlowProbe index="4">
    </FlowProbe>
    <FlowProbe index="5">
    </FlowProbe>
  </FlowProbes>
</FlowMonitor>

可能是什么原因?

最佳答案

作为替代方案,可以使用回调。

...
static void PrintRx ( Ptr< const Packet > p, const Address &ad )
{
   std::string traceLine = boost::lexical_cast< string >( *p );
   std::cout << Simulator::Now().GetSeconds () << " " << traceLine << std::endl; 
}

int main (int argc, char *argv[])
{                       
...
Config::ConnectWithoutContext ("/NodeList/*/ApplicationList/0/$ns3::PacketSink/Rx", MakeCallback (&PrintRx));
Packet::EnablePrinting ();
...

如下图可以看到接收到的数据包的内容,然后创建自己的统计分析工具。

...                                                               
19.881 ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 3192 protocol 2 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700)
19.8866 ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 3193 protocol 2 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700)
19.8922 ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 3194 protocol 2 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700)
19.8978 ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 3195 protocol 2 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700)
19.9034 ns3::Ipv4Header (tos 0x0 DSCP Default ECN Not-ECT ttl 62 id 3196 protocol 2 offset (bytes) 0 flags [none] length: 720 10.1.1.1 > 10.1.3.3) Payload (size=700)
...

关于c++ - FlowMonitor 不显示统计数据,但 PyViz 和跟踪文件显示它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15986586/

相关文章:

java - 计算 NS2 中 UDP 数据包的哈希值

c++ - 传递 ‘const Link’ 作为 ‘this’ 的 ‘std::string GetAttribute(std::string)’ 参数丢弃限定符

c++ - 为什么 std::forward 将我的左值变成右值?

c++ - 如何将单元测试添加到 Visual Studio 2012 中的 C++ 控制台程序?

c - 服务器不读取来自客户端的消息

network-programming - 当我在没有指定端口的情况下在浏览器中转到 localhost 时会发生什么?

python - 列出本地网络设备python的IP/MAC/名称

c++ - 生成 (void *) 数据的 Hash Key

c++ - 我想删除背景(就像黑环)

c++ - MD5代码覆盖率