E2E Delay and Throughput

1,074 views
Skip to first unread message

Urvik Upadhyay

unread,
Apr 17, 2014, 10:26:49 AM4/17/14
to ns-3-...@googlegroups.com
A quick question here, can I use CallBack statements to calculate E2E Delay and throughput between two particular nodes? For example, to calculate receive packets I'm using the following code:
void ReceivePacket (Ptr<Socket> socket)
{
 
  NS_LOG_UNCOND ("Received One packet!");
  uint32_t bytesTotal = 0;
   Ptr<Packet> packet;
   while(packet = socket->Recv())
    {
        bytesTotal += packet->GetSize ();
              packetsReceived += 1;
        }
  
}

I can't use flow monitor for GPSR as it is not meant to calculate results for loopback conditions.

Tommaso Pecorella

unread,
Apr 17, 2014, 2:06:40 PM4/17/14
to ns-3-...@googlegroups.com
Hi,

see UdpClient and UdpServer. The answer is there.

T.

Urvik Upadhyay

unread,
Apr 18, 2014, 1:33:28 AM4/18/14
to ns-3-...@googlegroups.com
Hey there!!

I edited my ReceivePacket method to get the throughput. The code is:


void ReceivePacket (Ptr<Socket> socket)
{
 
  NS_LOG_UNCOND ("Received One packet!");
 
   Ptr<Packet> packet;
   while(packet = socket->Recv())
    {
        bytesTotal += packet->GetSize ();
              packetsReceived += 1;
      
    throughput = (bytesTotal * 8) / (1024 * ( (Simulator::Now()).GetSeconds ()));
        }
  
}

The output I'm getting is 3.23202
Is it correct? Kindly check the code. :)

Tommaso Pecorella

unread,
Apr 18, 2014, 2:13:09 AM4/18/14
to ns-3-...@googlegroups.com


On Friday, April 18, 2014 4:25:44 AM UTC+2, Urvik Upadhyay wrote:


On Thursday, 17 April 2014 23:36:40 UTC+5:30, Tommaso Pecorella wrote:
Hi,

see UdpClient and UdpServer. The answer is there.

Hi Tommaso thanks for replying!! I saw UdpClient and UdpServer. But it only gives packets lost/packets received and I already have that. And the main thing is, I'm not using UdpClient Server app. Here is my code. Kindly have a look at it. And if possible help me to write callbacks for throughput and E2EDelay between my sender(11) and receiver(26) socket.


Hi,

you said you looked at UdpServer.cc, but I see you didn't saw them. There's quite a difference.

void
UdpServer::HandleRead (Ptr<Socket> socket)
{
  NS_LOG_FUNCTION
(this << socket);
 
Ptr<Packet> packet;
 
Address from;
 
while ((packet = socket->RecvFrom (from)))
   
{
     
if (packet->GetSize () > 0)
       
{
         
SeqTsHeader seqTs;
          packet
->RemoveHeader (seqTs);
          uint32_t currentSequenceNumber
= seqTs.GetSeq ();
         
if (InetSocketAddress::IsMatchingType (from))
           
{
              NS_LOG_INFO
("TraceDelay: RX " << packet->GetSize () <<
                           
" bytes from "<< InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
                           
" Sequence Number: " << currentSequenceNumber <<
                           
" Uid: " << packet->GetUid () <<
                           
" TXtime: " << seqTs.GetTs () <<
                           
" RXtime: " << Simulator::Now () <<
                           
" Delay: " << Simulator::Now () - seqTs.GetTs ());
           
}
         
else if (Inet6SocketAddress::IsMatchingType (from))
           
{
              NS_LOG_INFO
("TraceDelay: RX " << packet->GetSize () <<
                           
" bytes from "<< Inet6SocketAddress::ConvertFrom (from).GetIpv6 () <<
                           
" Sequence Number: " << currentSequenceNumber <<
                           
" Uid: " << packet->GetUid () <<
                           
" TXtime: " << seqTs.GetTs () <<
                           
" RXtime: " << Simulator::Now () <<
                           
" Delay: " << Simulator::Now () - seqTs.GetTs ());
           
}


          m_lossCounter
.NotifyReceived (currentSequenceNumber);
          m_received
++;
       
}
   
}
}


The SeqTs header is what you had to see. It will give you both the way to check for lost packets and the way to calculate the delay.

About the throughput, what you got is the Goodput (the equivalent, but calculated at application level). You're missing the UDP, Ip and MAC headers and trailers.

T.

 

Urvik Upadhyay

unread,
Apr 18, 2014, 2:44:04 AM4/18/14
to ns-3-...@googlegroups.com
Hi,

you said you looked at UdpServer.cc, but I see you didn't saw them. There's quite a difference.

I did!! But I thought you were talking about this!! :D
Thanks for pointing that out dear. I applied the same formula in flow monitor for my aodv part. Is that also good put and not throughput?
Flow Mon Code is:
            std::cout << "  Throughput: " << i->second.rxBytes * 8.0 / (i->second.timeLastRxPacket.GetSeconds() - i->second.timeFirstTxPacket.GetSeconds())/1024  << " Kbps\n";
 
And also, how to add all the headers in my code of ReceivePacket()? Do I need to make another callback?

Yacine Henou

unread,
May 5, 2014, 7:19:47 AM5/5/14
to ns-3-...@googlegroups.com
Hello,
I try too use flow monitor with gpsr but no succes. have you found something to evaluate gpsr performence ?  

Konstantinos

unread,
May 5, 2014, 12:25:48 PM5/5/14
to ns-3-...@googlegroups.com
This is not correct, because you calculate the throughput on every packet reception and you use the current simulation time.

Reception throughput is calculated as total bytes that you have received divided by the time difference from the first received till the last received.
So, you need two more variables; time of first Rx and time of last Rx packet. 

Urvik Upadhyay

unread,
Apr 17, 2014, 10:25:44 PM4/17/14
to ns-3-...@googlegroups.com


On Thursday, 17 April 2014 23:36:40 UTC+5:30, Tommaso Pecorella wrote:
Hi,

see UdpClient and UdpServer. The answer is there.
Hi Tommaso thanks for replying!! I saw UdpClient and UdpServer. But it only gives packets lost/packets received and I already have that. And the main thing is, I'm not using UdpClient Server app. Here is my code. Kindly have a look at it. And if possible help me to write callbacks for throughput and E2EDelay between my sender(11) and receiver(26) socket.


#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/ns2-mobility-helper.h"
#include "ns3/applications-module.h"
#include "ns3/config-store-module.h"
#include "ns3/wifi-module.h"
#include "ns3/internet-module.h"
#include "ns3/aodv-module.h"
#include "ns3/olsr-helper.h"
#include "ns3/gpsr-module.h"
#include "ns3/stats-module.h"


#include "ns3/flow-monitor-module.h"

#include <iostream>
#include <fstream>
#include <vector>
#include <string>

NS_LOG_COMPONENT_DEFINE ("WifiSimpleAdhoc");

using namespace ns3;

int packetsReceived = 0;

void ReceivePacket (Ptr<Socket> socket)
{
 
  NS_LOG_UNCOND ("Received One packet!");
  uint32_t bytesTotal = 0;
   Ptr<Packet> packet;
   while(packet = socket->Recv())
    {
        bytesTotal += packet->GetSize ();
              packetsReceived += 1;
        }
  
}
static void GenerateTraffic (Ptr<Socket> socket, uint32_t pktSize,
                             uint32_t pktCount, Time pktInterval )
{
  if (pktCount > 0)
    {
      socket->Send (Create<Packet> (pktSize));
      Simulator::Schedule (pktInterval, &GenerateTraffic,
                           socket, pktSize,pktCount-1, pktInterval);
    }
  else
    {
      socket->Close ();
    }

}

int main (int argc, char *argv[])
{
  std::string phyMode ("DsssRate1Mbps");
  uint32_t packetSize = 1024; // bytes
  uint32_t numPackets = 50;
  uint32_t nNodes = 30;
  double interval = 2.0; // seconds

  CommandLine cmd;

  cmd.AddValue ("phyMode", "Wifi Phy mode", phyMode);
  cmd.AddValue("nNodes", "Number of Nodes", nNodes);
  cmd.AddValue ("packetSize", "size of application packet sent", packetSize);
  cmd.AddValue ("numPackets", "number of packets generated", numPackets);
  cmd.AddValue ("interval", "interval (seconds) between packets", interval);

  cmd.Parse (argc, argv);
  // Convert to time object
  Time interPacketInterval = Seconds (interval);

 


  // disable fragmentation for frames below 2200 bytes
  Config::SetDefault ("ns3::WifiRemoteStationManager::FragmentationThreshold", StringValue ("22000"));
  // turn off RTS/CTS for frames below 2200 bytes
  Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", StringValue ("2200"));
  // Fix non-unicast data rate to be the same as that of unicast
  Config::SetDefault ("ns3::WifiRemoteStationManager::NonUnicastMode",
                      StringValue (phyMode));

  NodeContainer c;
  c.Create (nNodes);

  // The below set of helpers will help us to put together the wifi NICs we want
  WifiHelper wifi;
  wifi.SetStandard (WIFI_PHY_STANDARD_80211b);

  YansWifiPhyHelper wifiPhy =  YansWifiPhyHelper::Default ();
  // This is one parameter that matters when using FixedRssLossModel
  // set it to zero; otherwise, gain will be added
  //wifiPhy.Set ("RxGain", DoubleValue (0) );
  // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
  wifiPhy.SetPcapDataLinkType (YansWifiPhyHelper::DLT_IEEE802_11_RADIO);

  YansWifiChannelHelper wifiChannel;
  wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
  // The below FixedRssLossModel will cause the rss to be fixed regardless
  // of the distance between the two stations, and the transmit power
 // wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",DoubleValue (rss));
  wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel");
  wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel","MinDistance",DoubleValue (100));
 
  wifiPhy.SetChannel (wifiChannel.Create ());

  // Add a non-QoS upper mac, and disable rate control
  NqosWifiMacHelper wifiMac = NqosWifiMacHelper::Default ();
  wifi.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                "DataMode",StringValue (phyMode),
                                "ControlMode",StringValue (phyMode));
  // Set it to adhoc mode
  wifiMac.SetType ("ns3::AdhocWifiMac");
  NetDeviceContainer devices = wifi.Install (wifiPhy, wifiMac, c);

  Ns2MobilityHelper ns2 = Ns2MobilityHelper ("scratch/s30mob.tcl");
  ns2.Install ();
 
//  AodvHelper aodv;
  // OlsrHelper olsr;
  GpsrHelper gpsr;
 
  //aodv.Install();

  InternetStackHelper internet;
  internet.SetRoutingHelper (gpsr);
  internet.Install (c);
  gpsr.Install ();

  Ipv4AddressHelper ipv4;
  NS_LOG_INFO ("Assign IP Addresses.");
  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
  Ipv4InterfaceContainer i = ipv4.Assign (devices);

  
  uint16_t Port = 12345;
  
  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
 
 
  Ptr<Socket> recvSink = Socket::CreateSocket (c.Get (26), tid);
  InetSocketAddress local = InetSocketAddress ((Ipv4Address::GetAny())/*("10.1.1.4")*/, Port);
  recvSink->Bind (local);
  recvSink->SetRecvCallback (MakeCallback (&ReceivePacket));
 
  Ptr<Socket> source;
  source = Socket::CreateSocket (c.Get (11), tid);
  InetSocketAddress remote = InetSocketAddress (("10.1.1.27"), Port);
  //source->SetAllowBroadcast (true);
  source->Connect (remote);
 
   //Tracing
//   AsciiTraceHelper ascii;
  //wifiPhy.EnableAsciiAll (ascii.CreateFileStream("scratch/30nodes.tr"));//, devices);
    wifiPhy.EnablePcap("scratch/30nodes",devices);


  FlowMonitorHelper flowmon;
  Ptr<FlowMonitor> monitor = flowmon.Install(c);

        // Output what we are doing
  NS_LOG_UNCOND ("Testing " << numPackets  << " packets sent " );
 
 
  Simulator::ScheduleWithContext (source->GetNode ()->GetId (), Seconds (1.0), &GenerateTraffic, source, packetSize, numPackets, interPacketInterval);
  Simulator::Stop(Seconds (120));
  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 / (i->second.timeLastRxPacket.GetSeconds() - i->second.timeFirstTxPacket.GetSeconds())/1024  << " Kbps\n";
          std::cout << "transmitted packets: " <<i->second.txPackets << "\n";     
          std::cout << "recived packets: " <<i->second.rxPackets << "\n";
          std::cout<< " Lost Packets: " << ((i->second.txBytes) - (i->second.rxBytes))/ packetSize <<"\n";
       //   std::cout << "  Delay Sum:   " << i->second.delaySum / 1000000 << "ms\n";
     }


  monitor->SerializeToXmlFile("scratch/new30_1.flowmon", true, true);

  Simulator::Destroy ();
  std::cout << "packets received are " << packetsReceived << "\n";

  return 0;
}


When I run this command, I get some output like this..
OUTPUT:
Received One packet!
Received One packet!
Received One packet!
Received One packet!
Received One packet!
Received One packet!
...
...
...
Flow 61 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   39816
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 36
recived packets: 0
 Lost Packets: 38
Flow 63 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 64 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 65 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 66 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 67 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 68 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   7742
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 7
recived packets: 0
 Lost Packets: 7
Flow 69 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
Flow 70 (10.1.1.12 -> 10.1.1.27)
  Tx Bytes:   1106
  Rx Bytes:   0
  Throughput: -0 Kbps
transmitted packets: 1
recived packets: 0
 Lost Packets: 1
packets received are 40




I was so happy with the flow monitor but now when it's not working(Strangely generating multiple flows for the same source and destination!! :O ), I HAVE TO try other ways to calculate PDR, E2E Delay and Throughput by any way as soon as possible as I've to submit my project this monday.

I tried to run example from examples/stats module but it generates error.

I'm also trying to learn how to use .tr(ASCII Trace) and .pcap files to calculate E2EDelay and Throughput but alas, no success.

You may find many of this stuff irrelevant, I'm sorry for that. Kindly ignore. It's just the frustration.
Reply all
Reply to author
Forward
0 new messages