you are right, but i've already had it in mind.
i show my program below:
// Delay Gnuplot
#include <fstream>
#include <iostream>
#include "ns3/core-module.h"
#include "ns3/common-module.h"
#include "ns3/node-module.h"
#include "ns3/helper-module.h"
#include "ns3/mobility-module.h"
#include "ns3/contrib-module.h"
#include "ns3/wifi-module.h"
#include "ns3/global-route-manager.h"
#include "ns3/olsr-routing-protocol.h"
#include "ns3/ipv4-routing-protocol.h"
#include "ns3/flow-monitor.h"
#include "ns3/ipv4-address.h"
#include "ns3/flow-classifier.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("test");
double DISTANCE = 150; //m
uint32_t NUM_NODES_SIDE = 3;
void
print_stats (FlowMonitor::FlowStats st)
{
std::cout << " Tx Bytes: " << st.txBytes << std::endl;
std::cout << " Rx Bytes: " << st.rxBytes << std::endl;
std::cout << " Tx Packets: " << st.txPackets << std::endl;
std::cout << " Rx Packets: " << st.rxPackets << std::endl;
std::cout << " Lost Packets: " << st.lostPackets << std::endl;
if (st.rxPackets > 0)
{
std::cout << " Mean{Delay}: " << (st.delaySum.GetSeconds() /
st.rxPackets);
std::cout << " Mean{Jitter}: " << (st.jitterSum.GetSeconds() /
(st.rxPackets-1));
std::cout << " Mean{Hop Count}: " << st.timesForwarded /
st.rxPackets + 1;
}
if (false)
{
std::cout << "Delay Histogram" << std::endl;
for (uint32_t i=0; i<st.delayHistogram.GetNBins (); i++)
std::cout << " " << i << "(" <<
st.delayHistogram.GetBinStart (i) << "-"
<< st.delayHistogram.GetBinEnd (i) << "): " <<
st.delayHistogram.GetBinCount (i) << std::endl;
std::cout << "Jitter Histogram" << std::endl;
for (uint32_t i=0; i<st.jitterHistogram.GetNBins (); i++ )
std::cout << " " << i << "(" <<
st.jitterHistogram.GetBinStart (i) << "-"
<< st.jitterHistogram.GetBinEnd (i) << "): " <<
st.jitterHistogram.GetBinCount (i) << std::endl;
std::cout << "PacketSize Histogram "<< std::endl;
for (uint32_t i=0; i<st.packetSizeHistogram.GetNBins (); i+
+ )
std::cout << " " << i << "(" << st.packetSizeHistogram.GetBinStart
(i) << "-"
<< st.packetSizeHistogram.GetBinEnd (i) << "): " <<
st.packetSizeHistogram.GetBinCount (i) << std::endl;
}
for (uint32_t i=0; i<st.packetsDropped.size (); i++)
std::cout << " Packets dropped by reason " << i << ": " <<
st.packetsDropped [i] << std::endl;
// for (uint32_t i=0; i<st.bytesDropped.size(); i++)
// std::cout << "Bytes dropped by reason " << i << ": " <<
st.bytesDropped[i] << std::endl;
}
int
main (int argc, char *argv []) {
uint32_t NumNodesSide = 0;
string Results("");
bool Plot = false;
CommandLine cmd;
cmd.AddValue ("NumNodesSide", "Grid side number of nodes (total
number of nodes will be this number squared)", NumNodesSide);
cmd.AddValue ("Results", "Write XML results to file", Results);
cmd.AddValue ("Plot", "Plot the results using the matplotlib python
module", Plot);
cmd.Parse (argc,argv);
YansWifiChannelHelper wifiChannel = YansWifiChannelHelper::Default
(); // Create a channel helper in a default working state. By
default, we create a channel model with a propagation delay equal to a
constant, the speed of light, and a propagation loss based on a log
distance model with a reference loss of 46.6777 dB at reference
distance of 1m.
// wifiChannel.SetPropagationDelay
("ns3::ConstantSpeedPropagationDelayModel");
// wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default (); //
Create a phy helper in a default working state.
wifiPhy.SetChannel (wifiChannel.Create ());
NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default (); //
Create a mac helper in a default working state. i.e., this is an adhoc
mac by default.
Ssid ssid = Ssid("wifi-default");
wifiMac.SetType ("ns3::AdhocWifiMac", "Ssid",
SsidValue(ssid)); // the NqosWifiMacHelper is going to
create MAC layers of the “ns3::NqapWifiMac” (Non-Qos Access Point)
type. We set the “BeaconGeneration” Attribute to true and also set an
interval between beacons of 2.5 seconds
WifiHelper wifi = WifiHelper::Default (); // Returns: a new
WifiHelper in a default state
wifi.SetRemoteStationManager ("ArfWifiManager"); // The
default state is defined as being an Adhoc MAC layer with an ARF rate
control algorithm and both objects using their default attribute
values. By default, configure MAC and PHY for 802.11a.
OlsrHelper olsr_routing;
Ipv4StaticRoutingHelper static_routing;
Ipv4ListRoutingHelper list_routing;
list_routing.Add (static_routing, 0);
list_routing.Add (olsr_routing, 100);
InternetStackHelper internet;
internet.SetRoutingHelper (list_routing);
Ipv4AddressHelper ipv4Address;
ipv4Address.SetBase ("10.0.0.0", "255.255.255.0");
uint16_t port = 9; // Discard port(RFC 863)
OnOffHelper onoff ("ns3::UdpSocketFactory",
Address(InetSocketAddress(Ipv4Address ("10.0.0.1"), port)));
onoff.SetAttribute ("DataRate", DataRateValue(DataRate
("100kbps")));
onoff.SetAttribute ("OnTime", RandomVariableValue (ConstantVariable
(1)));
onoff.SetAttribute ("OffTime", RandomVariableValue (ConstantVariable
(0)));
Ipv4InterfaceContainer addresses;
NodeContainer nodes;
if(NumNodesSide == 0)
NumNodesSide = NUM_NODES_SIDE;
for(uint32_t xi=0; xi<NumNodesSide; xi++)
{
for(uint32_t yi=0; yi<NumNodesSide; yi++)
{
Ptr<Node> node = CreateObject<Node>();
nodes.Add(node);
internet.Install (node);
Ptr<ConstantPositionMobilityModel> mobility =
CreateObject<ConstantPositionMobilityModel>();
mobility->SetPosition(Vector(xi*DISTANCE, yi*DISTANCE, 0));
node->AggregateObject(mobility);
NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac,
node);
Ipv4InterfaceContainer ipv4_interfaces = ipv4Address.Assign
(devices);
addresses.Add(ipv4_interfaces.Get(0));
}
}
OnOffHelper onOffHelper ("ns3::UdpSocketFactory", Address ());
for(uint32_t i=0; i<nodes.GetN (); i++)
{
Ipv4Address destaddr = addresses.GetAddress ((addresses.GetN () - 1
- i) % addresses.GetN ());
onOffHelper.SetAttribute ("Remote",
AddressValue(InetSocketAddress(destaddr, port)));
ApplicationContainer app = onOffHelper.Install (nodes.Get(i));
app.Start (Seconds (UniformVariable (20, 30).GetValue ()));
}
// internet.EnablePcapAll("wifi-olsr")
Ptr<FlowMonitor> monitor;
FlowMonitorHelper flowmon_helper;
// flowmon_helper.SetMonitorAttribute("StartTime",
TimeValue(Seconds(31)))
monitor = flowmon_helper.InstallAll();
monitor->SetAttribute("DelayBinWidth", DoubleValue(0.001));
monitor->SetAttribute("JitterBinWidth", DoubleValue(0.001));
monitor->SetAttribute("PacketSizeBinWidth", DoubleValue(20));
Simulator::Stop (Seconds (44.0));
Simulator::Run ();
monitor->CheckForLostPackets();
Ptr<FlowClassifier> classifier = flowmon_helper.GetClassifier();
if(Results == "")
{
string proto;
for (std::map< FlowId, FlowMonitor::FlowStats >::iterator
flow=monitor->GetFlowStats().begin(); flow!=monitor-
>GetFlowStats().end(); flow++)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(flow-
>first);
switch(t.protocol)
{
case(6):
proto = "TCP";
break;
case(17):
proto = "UDP";
break;
default:
exit(1);
}
std::cout << "FlowID: " << flow->first << "(" << proto << " "
<< t.sourceAddress << "/" << t.sourcePort << " --> "
<< t.destinationAddress << "/" << t.destinationPort << ")" <<
std::endl;
print_stats(flow->second);
}
}
else
monitor->SerializeToXmlFile(Results, true, true);
if(Plot)
{
Gnuplot gnuplot("DELAYSbyFLOW.png");
Gnuplot2dDataset dataset;
dataset.SetStyle(Gnuplot2dDataset::HISTEPS);
for (std::map< FlowId, FlowMonitor::FlowStats >::iterator
flow=monitor->GetFlowStats().begin(); flow!=monitor-
>GetFlowStats().end(); flow++)
{
Ipv4FlowClassifier::FiveTuple tupl = classifier->FindFlow(flow-
>first);
if(tupl.protocol == 17 && tupl.sourcePort == 698)
continue;
dataset.Add((double)flow->first, (double)flow-
>second.delaySum.GetSeconds() / (double)flow->second.rxPackets);
}
gnuplot.AddDataset(dataset);
gnuplot.GenerateOutput(std::cout);
}
Simulator::Destroy ();
return 0;
}
In this line "Ptr<FlowClassifier> classifier =
flowmon_helper.GetClassifier();", "flowmon_helper.GetClassifier()"
should return variable of type ns3::Ipv4FlowClassifier to variable
"classifier" and not of type ns3::FlowClassifier, because after it's
needed to use "classifier->FindFlow(flow->first)" that return a
pointer to ns3::Ipv4FlowClassifier::FiveTuple struct
("Ipv4FlowClassifier::FiveTuple tupl = classifier->FindFlow(flow-
>first);") and the class ns3::FlowClassifier (
http://www.nsnam.org/
doxygen-release/classns3_1_1_flow_classifier.html) don't have function
"FindFlow".