A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
flow-monitor.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 //
3 // Copyright (c) 2009 INESC Porto
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License version 2 as
7 // published by the Free Software Foundation;
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 //
18 // Author: Gustavo J. A. M. Carneiro <gjc@inescporto.pt> <gjcarneiro@gmail.com>
19 //
20 
21 #include "flow-monitor.h"
22 #include "ns3/simulator.h"
23 #include "ns3/log.h"
24 #include "ns3/double.h"
25 #include <fstream>
26 #include <sstream>
27 
28 #define INDENT(level) for (int __xpto = 0; __xpto < level; __xpto++) os << ' ';
29 
30 #define PERIODIC_CHECK_INTERVAL (Seconds (1))
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("FlowMonitor")
35  ;
36 
37 NS_OBJECT_ENSURE_REGISTERED (FlowMonitor)
38  ;
39 
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::FlowMonitor")
45  .SetParent<Object> ()
46  .AddConstructor<FlowMonitor> ()
47  .AddAttribute ("MaxPerHopDelay", ("The maximum per-hop delay that should be considered. "
48  "Packets still not received after this delay are to be considered lost."),
49  TimeValue (Seconds (10.0)),
50  MakeTimeAccessor (&FlowMonitor::m_maxPerHopDelay),
51  MakeTimeChecker ())
52  .AddAttribute ("StartTime", ("The time when the monitoring starts."),
53  TimeValue (Seconds (0.0)),
54  MakeTimeAccessor (&FlowMonitor::Start),
55  MakeTimeChecker ())
56  .AddAttribute ("DelayBinWidth", ("The width used in the delay histogram."),
57  DoubleValue (0.001),
58  MakeDoubleAccessor (&FlowMonitor::m_delayBinWidth),
59  MakeDoubleChecker <double> ())
60  .AddAttribute ("JitterBinWidth", ("The width used in the jitter histogram."),
61  DoubleValue (0.001),
62  MakeDoubleAccessor (&FlowMonitor::m_jitterBinWidth),
63  MakeDoubleChecker <double> ())
64  .AddAttribute ("PacketSizeBinWidth", ("The width used in the packetSize histogram."),
65  DoubleValue (20),
66  MakeDoubleAccessor (&FlowMonitor::m_packetSizeBinWidth),
67  MakeDoubleChecker <double> ())
68  .AddAttribute ("FlowInterruptionsBinWidth", ("The width used in the flowInterruptions histogram."),
69  DoubleValue (0.250),
70  MakeDoubleAccessor (&FlowMonitor::m_flowInterruptionsBinWidth),
71  MakeDoubleChecker <double> ())
72  .AddAttribute ("FlowInterruptionsMinTime", ("The minimum inter-arrival time that is considered a flow interruption."),
73  TimeValue (Seconds (0.5)),
74  MakeTimeAccessor (&FlowMonitor::m_flowInterruptionsMinTime),
75  MakeTimeChecker ())
76  ;
77  return tid;
78 }
79 
80 TypeId
82 {
83  return GetTypeId ();
84 }
85 
87  : m_enabled (false)
88 {
89  // m_histogramBinWidth=DEFAULT_BIN_WIDTH;
90 }
91 
92 void
94 {
95  m_classifier = 0;
96  for (uint32_t i = 0; i < m_flowProbes.size (); i++)
97  {
98  m_flowProbes[i]->Dispose ();
99  m_flowProbes[i] = 0;
100  }
102 }
103 
106 {
107  std::map<FlowId, FlowStats>::iterator iter;
108  iter = m_flowStats.find (flowId);
109  if (iter == m_flowStats.end ())
110  {
111  FlowMonitor::FlowStats &ref = m_flowStats[flowId];
112  ref.delaySum = Seconds (0);
113  ref.jitterSum = Seconds (0);
114  ref.lastDelay = Seconds (0);
115  ref.txBytes = 0;
116  ref.rxBytes = 0;
117  ref.txPackets = 0;
118  ref.rxPackets = 0;
119  ref.lostPackets = 0;
120  ref.timesForwarded = 0;
125  return ref;
126  }
127  else
128  {
129  return iter->second;
130  }
131 }
132 
133 
134 void
135 FlowMonitor::ReportFirstTx (Ptr<FlowProbe> probe, uint32_t flowId, uint32_t packetId, uint32_t packetSize)
136 {
137  if (!m_enabled)
138  {
139  return;
140  }
141  Time now = Simulator::Now ();
142  TrackedPacket &tracked = m_trackedPackets[std::make_pair (flowId, packetId)];
143  tracked.firstSeenTime = now;
144  tracked.lastSeenTime = tracked.firstSeenTime;
145  tracked.timesForwarded = 0;
146  NS_LOG_DEBUG ("ReportFirstTx: adding tracked packet (flowId=" << flowId << ", packetId=" << packetId
147  << ").");
148 
149  probe->AddPacketStats (flowId, packetSize, Seconds (0));
150 
151  FlowStats &stats = GetStatsForFlow (flowId);
152  stats.txBytes += packetSize;
153  stats.txPackets++;
154  if (stats.txPackets == 1)
155  {
156  stats.timeFirstTxPacket = now;
157  }
158  stats.timeLastTxPacket = now;
159 }
160 
161 
162 void
163 FlowMonitor::ReportForwarding (Ptr<FlowProbe> probe, uint32_t flowId, uint32_t packetId, uint32_t packetSize)
164 {
165  if (!m_enabled)
166  {
167  return;
168  }
169  std::pair<FlowId, FlowPacketId> key (flowId, packetId);
170  TrackedPacketMap::iterator tracked = m_trackedPackets.find (key);
171  if (tracked == m_trackedPackets.end ())
172  {
173  NS_LOG_WARN ("Received packet forward report (flowId=" << flowId << ", packetId=" << packetId
174  << ") but not known to be transmitted.");
175  return;
176  }
177 
178  tracked->second.timesForwarded++;
179  tracked->second.lastSeenTime = Simulator::Now ();
180 
181  Time delay = (Simulator::Now () - tracked->second.firstSeenTime);
182  probe->AddPacketStats (flowId, packetSize, delay);
183 }
184 
185 
186 void
187 FlowMonitor::ReportLastRx (Ptr<FlowProbe> probe, uint32_t flowId, uint32_t packetId, uint32_t packetSize)
188 {
189  if (!m_enabled)
190  {
191  return;
192  }
193  TrackedPacketMap::iterator tracked = m_trackedPackets.find (std::make_pair (flowId, packetId));
194  if (tracked == m_trackedPackets.end ())
195  {
196  NS_LOG_WARN ("Received packet last-tx report (flowId=" << flowId << ", packetId=" << packetId
197  << ") but not known to be transmitted.");
198  return;
199  }
200 
201  Time now = Simulator::Now ();
202  Time delay = (now - tracked->second.firstSeenTime);
203  probe->AddPacketStats (flowId, packetSize, delay);
204 
205  FlowStats &stats = GetStatsForFlow (flowId);
206  stats.delaySum += delay;
207  stats.delayHistogram.AddValue (delay.GetSeconds ());
208  if (stats.rxPackets > 0 )
209  {
210  Time jitter = stats.lastDelay - delay;
211  if (jitter > Seconds (0))
212  {
213  stats.jitterSum += jitter;
214  stats.jitterHistogram.AddValue (jitter.GetSeconds ());
215  }
216  else
217  {
218  stats.jitterSum -= jitter;
219  stats.jitterHistogram.AddValue (-jitter.GetSeconds ());
220  }
221  }
222  stats.lastDelay = delay;
223 
224  stats.rxBytes += packetSize;
225  stats.packetSizeHistogram.AddValue ((double) packetSize);
226  stats.rxPackets++;
227  if (stats.rxPackets == 1)
228  {
229  stats.timeFirstRxPacket = now;
230  }
231  else
232  {
233  // measure possible flow interruptions
234  Time interArrivalTime = now - stats.timeLastRxPacket;
235  if (interArrivalTime > m_flowInterruptionsMinTime)
236  {
237  stats.flowInterruptionsHistogram.AddValue (interArrivalTime.GetSeconds ());
238  }
239  }
240  stats.timeLastRxPacket = now;
241  stats.timesForwarded += tracked->second.timesForwarded;
242 
243  NS_LOG_DEBUG ("ReportLastTx: removing tracked packet (flowId="
244  << flowId << ", packetId=" << packetId << ").");
245 
246  m_trackedPackets.erase (tracked); // we don't need to track this packet anymore
247 }
248 
249 void
250 FlowMonitor::ReportDrop (Ptr<FlowProbe> probe, uint32_t flowId, uint32_t packetId, uint32_t packetSize,
251  uint32_t reasonCode)
252 {
253  if (!m_enabled)
254  {
255  return;
256  }
257 
258  probe->AddPacketDropStats (flowId, packetSize, reasonCode);
259 
260  FlowStats &stats = GetStatsForFlow (flowId);
261  stats.lostPackets++;
262  if (stats.packetsDropped.size () < reasonCode + 1)
263  {
264  stats.packetsDropped.resize (reasonCode + 1, 0);
265  stats.bytesDropped.resize (reasonCode + 1, 0);
266  }
267  ++stats.packetsDropped[reasonCode];
268  stats.bytesDropped[reasonCode] += packetSize;
269  NS_LOG_DEBUG ("++stats.packetsDropped[" << reasonCode<< "]; // becomes: " << stats.packetsDropped[reasonCode]);
270 
271  TrackedPacketMap::iterator tracked = m_trackedPackets.find (std::make_pair (flowId, packetId));
272  if (tracked != m_trackedPackets.end ())
273  {
274  // we don't need to track this packet anymore
275  // FIXME: this will not necessarily be true with broadcast/multicast
276  NS_LOG_DEBUG ("ReportDrop: removing tracked packet (flowId="
277  << flowId << ", packetId=" << packetId << ").");
278  m_trackedPackets.erase (tracked);
279  }
280 }
281 
282 std::map<FlowId, FlowMonitor::FlowStats>
284 {
285  return m_flowStats;
286 }
287 
288 
289 void
291 {
292  Time now = Simulator::Now ();
293 
294  for (TrackedPacketMap::iterator iter = m_trackedPackets.begin ();
295  iter != m_trackedPackets.end (); )
296  {
297  if (now - iter->second.lastSeenTime >= maxDelay)
298  {
299  // packet is considered lost, add it to the loss statistics
300  std::map<FlowId, FlowStats>::iterator
301  flow = m_flowStats.find (iter->first.first);
302  NS_ASSERT (flow != m_flowStats.end ());
303  flow->second.lostPackets++;
304 
305  // we won't track it anymore
306  m_trackedPackets.erase (iter++);
307  }
308  else
309  {
310  iter++;
311  }
312  }
313 }
314 
315 void
317 {
319 }
320 
321 void
323 {
326 }
327 
328 void
330 {
333 }
334 
335 void
337 {
338  m_flowProbes.push_back (probe);
339 }
340 
341 std::vector< Ptr<FlowProbe> >
343 {
344  return m_flowProbes;
345 }
346 
347 
348 void
350 {
351  if (m_enabled)
352  {
353  return;
354  }
357 }
358 
359 void
360 FlowMonitor::Stop (const Time &time)
361 {
362  if (!m_enabled)
363  {
364  return;
365  }
368 }
369 
370 
371 void
373 {
374  if (m_enabled)
375  {
376  return;
377  }
378  m_enabled = true;
379 }
380 
381 
382 void
384 {
385  if (!m_enabled)
386  {
387  return;
388  }
389  m_enabled = false;
391 }
392 
393 void
395 {
396  m_classifier = classifier;
397 }
398 
399 void
400 FlowMonitor::SerializeToXmlStream (std::ostream &os, int indent, bool enableHistograms, bool enableProbes)
401 {
403 
404  INDENT (indent); os << "<FlowMonitor>\n";
405  indent += 2;
406  INDENT (indent); os << "<FlowStats>\n";
407  indent += 2;
408  for (std::map<FlowId, FlowStats>::const_iterator flowI = m_flowStats.begin ();
409  flowI != m_flowStats.end (); flowI++)
410  {
411 
412  INDENT (indent);
413 #define ATTRIB(name) << " " # name "=\"" << flowI->second.name << "\""
414  os << "<Flow flowId=\"" << flowI->first << "\""
415  ATTRIB (timeFirstTxPacket)
416  ATTRIB (timeFirstRxPacket)
417  ATTRIB (timeLastTxPacket)
418  ATTRIB (timeLastRxPacket)
419  ATTRIB (delaySum)
420  ATTRIB (jitterSum)
421  ATTRIB (lastDelay)
422  ATTRIB (txBytes)
423  ATTRIB (rxBytes)
424  ATTRIB (txPackets)
425  ATTRIB (rxPackets)
426  ATTRIB (lostPackets)
427  ATTRIB (timesForwarded)
428  << ">\n";
429 #undef ATTRIB
430 
431 
432  indent += 2;
433  for (uint32_t reasonCode = 0; reasonCode < flowI->second.packetsDropped.size (); reasonCode++)
434  {
435  INDENT (indent);
436  os << "<packetsDropped reasonCode=\"" << reasonCode << "\""
437  << " number=\"" << flowI->second.packetsDropped[reasonCode]
438  << "\" />\n";
439  }
440  for (uint32_t reasonCode = 0; reasonCode < flowI->second.bytesDropped.size (); reasonCode++)
441  {
442  INDENT (indent);
443  os << "<bytesDropped reasonCode=\"" << reasonCode << "\""
444  << " bytes=\"" << flowI->second.bytesDropped[reasonCode]
445  << "\" />\n";
446  }
447  if (enableHistograms)
448  {
449  flowI->second.delayHistogram.SerializeToXmlStream (os, indent, "delayHistogram");
450  flowI->second.jitterHistogram.SerializeToXmlStream (os, indent, "jitterHistogram");
451  flowI->second.packetSizeHistogram.SerializeToXmlStream (os, indent, "packetSizeHistogram");
452  flowI->second.flowInterruptionsHistogram.SerializeToXmlStream (os, indent, "flowInterruptionsHistogram");
453  }
454  indent -= 2;
455 
456  INDENT (indent); os << "</Flow>\n";
457  }
458  indent -= 2;
459  INDENT (indent); os << "</FlowStats>\n";
460 
461  m_classifier->SerializeToXmlStream (os, indent);
462 
463  if (enableProbes)
464  {
465  INDENT (indent); os << "<FlowProbes>\n";
466  indent += 2;
467  for (uint32_t i = 0; i < m_flowProbes.size (); i++)
468  {
469  m_flowProbes[i]->SerializeToXmlStream (os, indent, i);
470  }
471  indent -= 2;
472  INDENT (indent); os << "</FlowProbes>\n";
473  }
474 
475  indent -= 2;
476  INDENT (indent); os << "</FlowMonitor>\n";
477 }
478 
479 
480 std::string
481 FlowMonitor::SerializeToXmlString (int indent, bool enableHistograms, bool enableProbes)
482 {
483  std::ostringstream os;
484  SerializeToXmlStream (os, indent, enableHistograms, enableProbes);
485  return os.str ();
486 }
487 
488 
489 void
490 FlowMonitor::SerializeToXmlFile (std::string fileName, bool enableHistograms, bool enableProbes)
491 {
492  std::ofstream os (fileName.c_str (), std::ios::out|std::ios::binary);
493  os << "<?xml version=\"1.0\" ?>\n";
494  SerializeToXmlStream (os, 0, enableHistograms, enableProbes);
495  os.close ();
496 }
497 
498 
499 } // namespace ns3
500 
#define PERIODIC_CHECK_INTERVAL
Definition: flow-monitor.cc:30
keep track of time values and allow control of global simulation resolution
Definition: nstime.h:81
smart pointer class similar to boost::intrusive_ptr
Definition: ptr.h:59
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
void CheckForLostPackets()
Check right now for packets that appear to be lost.
void StartRightNow()
Begin monitoring flows right now
uint32_t lostPackets
Total number of packets that are assumed to be lost, i.e.
Definition: flow-monitor.h:107
uint32_t rxPackets
Total number of received packets for the flow.
Definition: flow-monitor.h:100
uint32_t txPackets
Total number of transmitted packets for the flow.
Definition: flow-monitor.h:98
#define NS_ASSERT(condition)
Definition: assert.h:64
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
Time m_maxPerHopDelay
Minimum per-hop delay.
Definition: flow-monitor.h:265
static TypeId GetTypeId()
Get the type ID.
Definition: flow-monitor.cc:42
void ReportDrop(Ptr< FlowProbe > probe, FlowId flowId, FlowPacketId packetId, uint32_t packetSize, uint32_t reasonCode)
FlowProbe implementations are supposed to call this method to report that a known packet is being dro...
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: object.cc:336
static void Cancel(const EventId &id)
Set the cancel bit on this event: the event's associated function will not be invoked when it expires...
Definition: simulator.cc:268
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Schedule an event to expire at the relative time "time" is reached.
Definition: simulator.h:824
Time delaySum
Contains the sum of all end-to-end delays for all received packets of the flow.
Definition: flow-monitor.h:78
std::vector< uint64_t > bytesDropped
This attribute also tracks the number of lost bytes.
Definition: flow-monitor.h:136
std::map< FlowId, FlowStats > m_flowStats
FlowId –> FlowStats.
Definition: flow-monitor.h:260
Time m_flowInterruptionsMinTime
Flow interruptions minimum time.
Definition: flow-monitor.h:278
void ReportFirstTx(Ptr< FlowProbe > probe, FlowId flowId, FlowPacketId packetId, uint32_t packetSize)
FlowProbe implementations are supposed to call this method to report that a new packet was transmitte...
void SetFlowClassifier(Ptr< FlowClassifier > classifier)
Set the FlowClassifier to be used by the flow monitor.
TrackedPacketMap m_trackedPackets
Tracked packets.
Definition: flow-monitor.h:264
Time lastDelay
Contains the last measured delay of a packet It is stored to measure the packet's Jitter...
Definition: flow-monitor.h:91
std::map< FlowId, FlowStats > GetFlowStats() const
Retrieve all collected the flow statistics.
void SerializeToXmlStream(std::ostream &os, int indent, bool enableHistograms, bool enableProbes)
Serializes the results to an std::ostream in XML format.
double GetSeconds(void) const
Definition: nstime.h:274
Time firstSeenTime
absolute time when the packet was first seen by a probe
Definition: flow-monitor.h:254
hold objects of type ns3::Time
Definition: nstime.h:961
Time jitterSum
Contains the sum of all end-to-end delay jitter (delay variation) values for all received packets of ...
Definition: flow-monitor.h:87
std::string SerializeToXmlString(int indent, bool enableHistograms, bool enableProbes)
Same as SerializeToXmlStream, but returns the output as a std::string.
bool m_enabled
FlowMon is enabled.
Definition: flow-monitor.h:273
virtual void NotifyConstructionCompleted(void)
This method is invoked once all member attributes have been initialized.
Definition: object-base.cc:60
void SetDefaultBinWidth(double binWidth)
Set the bin width.
Definition: histogram.cc:67
Time timeFirstTxPacket
Contains the absolute time when the first packet in the flow was transmitted, i.e.
Definition: flow-monitor.h:60
double m_packetSizeBinWidth
packet size bin width (for histograms)
Definition: flow-monitor.h:276
FlowStats & GetStatsForFlow(FlowId flowId)
Get the stats for a given flow.
double m_jitterBinWidth
Jitter bin width (for histograms)
Definition: flow-monitor.h:275
EventId m_stopEvent
Stop event.
Definition: flow-monitor.h:272
Time lastSeenTime
absolute time when the packet was last seen by a probe
Definition: flow-monitor.h:255
double m_delayBinWidth
Delay bin width (for histograms)
Definition: flow-monitor.h:274
#define INDENT(level)
Definition: flow-monitor.cc:28
virtual void NotifyConstructionCompleted()
This method is invoked once all member attributes have been initialized.
#define ATTRIB(name)
void Stop(const Time &time)
Set the time, counting from the current time, from which to stop monitoring flows.
std::vector< Ptr< FlowProbe > > m_flowProbes
all the FlowProbes
Definition: flow-monitor.h:266
Time timeFirstRxPacket
Contains the absolute time when the first packet in the flow was received by an end node...
Definition: flow-monitor.h:65
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
uint32_t timesForwarded
Contains the number of times a packet has been reportedly forwarded, summed for all received packets ...
Definition: flow-monitor.h:111
Time timeLastRxPacket
Contains the absolute time when the last packet in the flow was received, i.e.
Definition: flow-monitor.h:74
void StopRightNow()
End monitoring flows right now
#define NS_LOG_WARN(msg)
Definition: log.h:280
Histogram delayHistogram
Histogram of the packet delays.
Definition: flow-monitor.h:114
void SerializeToXmlFile(std::string fileName, bool enableHistograms, bool enableProbes)
Same as SerializeToXmlStream, but writes to a file instead.
std::vector< Ptr< FlowProbe > > GetAllProbes() const
Get a list of all FlowProbe's associated with this FlowMonitor.
#define NS_LOG_DEBUG(msg)
Definition: log.h:289
Ptr< FlowClassifier > m_classifier
the FlowClassifier
Definition: flow-monitor.h:269
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
Definition: flow-monitor.cc:93
Histogram flowInterruptionsHistogram
histogram of durations of flow interruptions
Definition: flow-monitor.h:137
uint64_t txBytes
Total number of transmitted bytes for the flow.
Definition: flow-monitor.h:94
Structure that represents the measured metrics of an individual packet flow.
Definition: flow-monitor.h:55
double m_flowInterruptionsBinWidth
Flow interruptions bin width (for histograms)
Definition: flow-monitor.h:277
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
Definition: time.cc:452
Structure to represent a single tracked packet data.
Definition: flow-monitor.h:252
Histogram jitterHistogram
Histogram of the packet jitters.
Definition: flow-monitor.h:116
a base class which provides memory management and object aggregation
Definition: object.h:63
EventId m_startEvent
Start event.
Definition: flow-monitor.h:271
void Start(const Time &time)
Set the time, counting from the current time, from which to start monitoring flows.
void ReportForwarding(Ptr< FlowProbe > probe, FlowId flowId, FlowPacketId packetId, uint32_t packetSize)
FlowProbe implementations are supposed to call this method to report that a known packet is being for...
uint64_t rxBytes
Total number of received bytes for the flow.
Definition: flow-monitor.h:96
Hold a floating point type.
Definition: double.h:41
void AddValue(double value)
Add a value to the histogram.
Definition: histogram.cc:81
void PeriodicCheckForLostPackets()
Periodic function to check for lost packets and prune statistics.
uint32_t timesForwarded
number of times the packet was reportedly forwarded
Definition: flow-monitor.h:256
void AddProbe(Ptr< FlowProbe > probe)
Register a new FlowProbe that will begin monitoring and report events to this monitor.
a unique identifier for an interface.
Definition: type-id.h:49
Time timeLastTxPacket
Contains the absolute time when the last packet in the flow was transmitted, i.e. ...
Definition: flow-monitor.h:70
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void ReportLastRx(Ptr< FlowProbe > probe, FlowId flowId, FlowPacketId packetId, uint32_t packetSize)
FlowProbe implementations are supposed to call this method to report that a known packet is being rec...
Histogram packetSizeHistogram
Histogram of the packet sizes.
Definition: flow-monitor.h:118
TypeId GetInstanceTypeId() const
Definition: flow-monitor.cc:81
uint32_t FlowId
Abstract identifier of a packet flow.
std::vector< uint32_t > packetsDropped
This attribute also tracks the number of lost packets and bytes, but discriminates the losses by a re...
Definition: flow-monitor.h:132