Adding 3 new applications:udp-client, udp-server, udp-trace-client.
authorMohamed Amine Ismail <amine.ismail@sophia.inria.fr>
Fri, 27 Nov 2009 17:06:45 +0100
changeset 5781 2557c340ea15
parent 5780 1ae8031ed08f
child 5813 e7c95ceda997
Adding 3 new applications:udp-client, udp-server, udp-trace-client.
AUTHORS
examples/udp-client-server/udp-client-server.cc
examples/udp-client-server/udp-trace-client-server.cc
examples/udp-client-server/waf
examples/udp-client-server/wscript
examples/wscript
src/applications/udp-client-server/packet-loss-counter.cc
src/applications/udp-client-server/packet-loss-counter.h
src/applications/udp-client-server/seq-ts-header.cc
src/applications/udp-client-server/seq-ts-header.h
src/applications/udp-client-server/udp-client-server-test.cc
src/applications/udp-client-server/udp-client.cc
src/applications/udp-client-server/udp-client.h
src/applications/udp-client-server/udp-server.cc
src/applications/udp-client-server/udp-server.h
src/applications/udp-client-server/udp-trace-client.cc
src/applications/udp-client-server/udp-trace-client.h
src/applications/udp-client-server/waf
src/applications/udp-client-server/wscript
src/helper/udp-client-server-helper.cc
src/helper/udp-client-server-helper.h
src/helper/wscript
src/wscript
--- a/AUTHORS	Thu Nov 26 14:53:53 2009 +0100
+++ b/AUTHORS	Fri Nov 27 17:06:45 2009 +0100
@@ -12,6 +12,7 @@
 Luis Cortes (cortes@gatech.edu)
 Craig Dowell (craigdo@ee.washington.edu)
 David Gross (gdavid.devel@gmail.com)
+Mohamed Amine Ismail (amine.ismail@sophia.inria.fr, iamine@udcast.com)
 Tom Henderson (tomhend@u.washington.edu)
 Sam Jansen (sam.jansen@gmail.com)
 Liu Jian (liujatp@gmail.com)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/udp-client-server.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,104 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Network topology
+//
+//       n0    n1
+//       |     |
+//       =======
+//         LAN
+//
+// - UDP flows from n0 to n1
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("UdpClientServerExample");
+
+int
+main (int argc, char *argv[])
+{
+//
+// Enable logging for UdpClient and
+//
+  LogComponentEnable ("UdpClient", LOG_LEVEL_INFO);
+  LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer n;
+  n.Create (2);
+
+  InternetStackHelper internet;
+  internet.Install (n);
+
+  NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+  NetDeviceContainer d = csma.Install (n);
+
+  Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place.  Now we need to add IP addresses.
+//
+  NS_LOG_INFO ("Assign IP Addresses.");
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+  NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpClient application to send UDP datagrams from node zero to
+// node one.
+//
+  uint32_t MaxPacketSize = 1024;
+  Time interPacketInterval = Seconds (0.05);
+  uint32_t maxPacketCount = 320;
+  UdpClientHelper client (i.GetAddress (1), port);
+  client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+  client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+  client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (n.Get (0));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/udp-trace-client-server.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,100 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+// Network topology
+//
+//       n0    n1
+//       |     |
+//       =======
+//         LAN
+//
+// - UDP flows from n0 to n1
+
+#include <fstream>
+#include "ns3/core-module.h"
+#include "ns3/simulator-module.h"
+#include "ns3/helper-module.h"
+
+using namespace ns3;
+
+NS_LOG_COMPONENT_DEFINE ("UdpTraceClientServerExample");
+
+int
+main (int argc, char *argv[])
+{
+//
+// Enable logging for UdpClient and
+//
+  LogComponentEnable ("UdpTraceClient", LOG_LEVEL_INFO);
+  LogComponentEnable ("UdpServer", LOG_LEVEL_INFO);
+
+//
+// Explicitly create the nodes required by the topology (shown above).
+//
+  NS_LOG_INFO ("Create nodes.");
+  NodeContainer n;
+  n.Create (2);
+
+  InternetStackHelper internet;
+  internet.Install (n);
+
+  NS_LOG_INFO ("Create channels.");
+//
+// Explicitly create the channels required by the topology (shown above).
+//
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+  NetDeviceContainer d = csma.Install (n);
+
+  Ipv4AddressHelper ipv4;
+//
+// We've got the "hardware" in place.  Now we need to add IP addresses.
+//
+  NS_LOG_INFO ("Assign IP Addresses.");
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+  NS_LOG_INFO ("Create Applications.");
+//
+// Create one udpServer applications on node one.
+//
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Create one UdpTraceClient application to send UDP datagrams from node zero to
+// node one.
+//
+  uint32_t MaxPacketSize = 1400;
+  UdpTraceClientHelper client (i.GetAddress (1), port,"");
+  client.SetAttribute ("MaxPacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (n.Get (0));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+//
+// Now, do the actual simulation.
+//
+  NS_LOG_INFO ("Run Simulation.");
+  Simulator::Run ();
+  Simulator::Destroy ();
+  NS_LOG_INFO ("Done.");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/waf	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../waf "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/udp-client-server/wscript	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,8 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    obj = bld.create_ns3_program('udp-client-server', ['csma', 'internet-stack'])
+    obj.source = 'udp-client-server.cc'
+    
+    obj = bld.create_ns3_program('udp-trace-client-server', ['csma', 'internet-stack'])
+    obj.source = 'udp-trace-client-server.cc'
--- a/examples/wscript	Thu Nov 26 14:53:53 2009 +0100
+++ b/examples/wscript	Fri Nov 27 17:06:45 2009 +0100
@@ -20,3 +20,4 @@
         bld.add_subdirs('tutorial')
         bld.add_subdirs('udp')
         bld.add_subdirs('wireless')
+        bld.add_subdirs('udp-client-server')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/packet-loss-counter.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,124 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  Copyright (c) 2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/simulator.h"
+#include "ns3/uinteger.h"
+#include "packet-loss-counter.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("PacketLossCounter");
+
+
+PacketLossCounter::PacketLossCounter (uint8_t bitmapSize)
+  : m_lost (0),
+    m_bitMapSize (0),
+    m_lastMaxSeqNum (0),
+    m_receiveBitMap (0)
+{
+  SetBitMapSize (bitmapSize);
+}
+
+PacketLossCounter::~PacketLossCounter ()
+{
+  delete [] m_receiveBitMap;
+}
+
+uint16_t
+PacketLossCounter::GetBitMapSize () const
+{
+  return m_bitMapSize * 8;
+}
+
+void
+PacketLossCounter::SetBitMapSize (uint16_t winSize)
+{
+
+  NS_ASSERT_MSG(winSize%8==0,"The packet window size should be a multiple of 8");
+  m_bitMapSize = winSize/8;
+  if (m_receiveBitMap!=0)
+    {
+      delete [] m_receiveBitMap;
+    }
+  m_receiveBitMap = new uint8_t [m_bitMapSize] ();
+  memset (m_receiveBitMap,0,m_bitMapSize);
+}
+
+uint32_t
+PacketLossCounter::GetLost () const
+{
+  return m_lost;
+}
+
+bool
+PacketLossCounter::GetBit(uint32_t seqNum)
+{
+  return ((m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] >> (7-(seqNum%8)))&0x01);
+}
+
+void
+PacketLossCounter::SetBit(uint32_t seqNum, bool val)
+{
+  if (val)
+    {
+      m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] |= 0x80 >> (seqNum%8);
+    }
+  else
+    {
+      m_receiveBitMap[(seqNum%(m_bitMapSize*8))/8] &= ~(0x80 >> (seqNum%8));
+    }
+}
+
+/*
+ * This algo works as follows:
+ * When a packet is received:
+ * 1) From the last received packet to the current one:
+ *    1.1) check the corresponding bit in the bitMAP.
+ *    This bit indicates if the packet with (SeqNum-bitMapSizeInBit) is
+ *    received (1) or not (0)
+ *    1.2) Mark the packet as lost (0) in the bitMap
+ * 2) Mark the current packet as received (1) in the bitMap
+ * 3) Update the value of the last received packet
+ */
+
+void
+PacketLossCounter::NotifyReceived (uint32_t seqNum)
+{
+  if (seqNum>(uint32_t)(m_bitMapSize*8)-1)
+    {
+      for (uint32_t i=m_lastMaxSeqNum+1; i<=seqNum;i++)
+        {
+          if (GetBit(i)!=1)
+            {
+              NS_LOG_INFO ("Packet lost: " << i-(m_bitMapSize*8));
+              m_lost++;
+            }
+          SetBit(i, 0);
+        }
+    }
+  SetBit(seqNum, 1);
+  if (seqNum>m_lastMaxSeqNum)
+    {
+      m_lastMaxSeqNum = seqNum;
+    }
+}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/packet-loss-counter.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ *
+ */
+#ifndef _PACKET_LOSS_COUNTER_H_
+#define _PACKET_LOSS_COUNTER_H_
+
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/address.h"
+
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+class PacketLossCounter
+{
+public:
+  PacketLossCounter (uint8_t bitmapSize);
+  ~PacketLossCounter ();
+  void NotifyReceived (uint32_t seq);
+  uint32_t GetLost (void) const;
+  uint16_t GetBitMapSize (void) const;
+  void SetBitMapSize (uint16_t size);
+private:
+  bool GetBit (uint32_t seqNum);
+  void SetBit (uint32_t seqNum, bool val);
+
+  uint32_t m_lost;
+  uint16_t m_bitMapSize;
+  uint32_t m_lastMaxSeqNum;
+  uint8_t * m_receiveBitMap;
+};
+}
+
+#endif /* PACKETLOSSCOUNTER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/seq-ts-header.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,96 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#include "ns3/assert.h"
+#include "ns3/log.h"
+#include "ns3/header.h"
+#include "ns3/simulator.h"
+#include "seq-ts-header.h"
+
+NS_LOG_COMPONENT_DEFINE ("SeqTsHeader");
+
+namespace ns3 {
+
+NS_OBJECT_ENSURE_REGISTERED (SeqTsHeader);
+
+SeqTsHeader::SeqTsHeader ()
+  : m_seq (0),
+    m_ts (Simulator::Now ().GetTimeStep ())
+{}
+
+void 
+SeqTsHeader::SetSeq (uint32_t seq)
+{
+  m_seq = seq;
+}
+uint32_t 
+SeqTsHeader::GetSeq (void) const
+{
+  return m_seq;
+}
+
+Time 
+SeqTsHeader::GetTs (void) const
+{
+  return TimeStep (m_ts);
+}
+
+TypeId 
+SeqTsHeader::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::SeqTsHeader")
+    .SetParent<Header> ()
+    .AddConstructor<SeqTsHeader> ()
+    ;
+  return tid;
+}
+TypeId 
+SeqTsHeader::GetInstanceTypeId (void) const
+{
+  return GetTypeId ();
+}
+void 
+SeqTsHeader::Print (std::ostream &os) const
+{
+  os << "(seq=" << m_seq << " time=" << TimeStep (m_ts).GetSeconds () << ")";
+}
+uint32_t 
+SeqTsHeader::GetSerializedSize (void) const
+{
+  return 4+8;
+}
+
+void
+SeqTsHeader::Serialize (Buffer::Iterator start) const
+{
+  Buffer::Iterator i = start;
+  i.WriteHtonU32 (m_seq);
+  i.WriteHtonU64 (m_ts);
+}
+uint32_t
+SeqTsHeader::Deserialize (Buffer::Iterator start)
+{
+  Buffer::Iterator i = start;
+  m_seq = i.ReadNtohU32 ();
+  m_ts = i.ReadNtohU64 ();
+  return GetSerializedSize ();
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/seq-ts-header.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,61 @@
+/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2009 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
+ */
+
+#ifndef SEQ_TS_HEADER_H
+#define SEQ_TS_HEADER_H
+
+#include "ns3/header.h"
+#include "ns3/nstime.h"
+
+namespace ns3 {
+/**
+ * \ingroup udpclientserver
+ * \class SeqTsHeader
+ * \brief Packet header for Udp client/server application
+ * The header is made of a 32bits sequence number followed by
+ * a 64bits time stamp.
+ */
+class SeqTsHeader : public Header
+{
+public:
+  SeqTsHeader ();
+
+  /**
+   * \param seq the sequence number
+   */
+  void SetSeq (uint32_t seq);
+  uint32_t GetSeq (void) const;
+  Time GetTs (void) const;
+
+  static TypeId GetTypeId (void);
+ private:
+  virtual TypeId GetInstanceTypeId (void) const;
+  virtual void Print (std::ostream &os) const;
+  virtual uint32_t GetSerializedSize (void) const;
+  virtual void Serialize (Buffer::Iterator start) const;
+  virtual uint32_t Deserialize (Buffer::Iterator start);
+
+  uint32_t m_seq;
+  uint64_t m_ts;
+};
+
+} // namespace ns3
+
+#endif /* SEQ_TS_HEADER_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client-server-test.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,287 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                              <amine.ismail@udcast.com>
+ */
+
+#include <fstream>
+#include "ns3/log.h"
+#include "ns3/abort.h"
+#include "ns3/config.h"
+#include "ns3/string.h"
+#include "ns3/uinteger.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/point-to-point-helper.h"
+#include "ns3/internet-stack-helper.h"
+#include "ns3/ipv4-address-helper.h"
+#include "ns3/udp-client-server-helper.h"
+#include "ns3/csma-helper.h"
+#include "ns3/test.h"
+#include "ns3/simulator.h"
+
+using namespace ns3;
+
+/**
+ * Test that all the udp packets generated by an udpClient application are
+ * correctly received by an udpServer application
+ */
+
+class UdpClientServerTestCase: public TestCase
+{
+public:
+  UdpClientServerTestCase ();
+  virtual ~UdpClientServerTestCase ();
+
+private:
+  virtual bool DoRun (void);
+
+};
+
+UdpClientServerTestCase::UdpClientServerTestCase () :
+  TestCase ("Test that all the udp packets generated by an udpClient application are correctly received by an udpServer application")
+{
+}
+
+UdpClientServerTestCase::~UdpClientServerTestCase ()
+{
+}
+
+bool UdpClientServerTestCase::DoRun (void)
+{
+    NodeContainer n;
+    n.Create (2);
+
+    InternetStackHelper internet;
+    internet.Install (n);
+
+    CsmaHelper csma;
+    csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+    csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+    csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+    NetDeviceContainer d = csma.Install (n);
+
+    Ipv4AddressHelper ipv4;
+
+    ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+    Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+    uint16_t port = 4000;
+    UdpServerHelper server (port);
+    ApplicationContainer apps = server.Install (n.Get(1));
+    apps.Start (Seconds (1.0));
+    apps.Stop (Seconds (10.0));
+
+    uint32_t MaxPacketSize = 1024;
+    Time interPacketInterval = Seconds (1.);
+    uint32_t maxPacketCount = 10;
+    UdpClientHelper client (i.GetAddress (1), port);
+    client.SetAttribute ("MaxPackets", UintegerValue (maxPacketCount));
+    client.SetAttribute ("Interval", TimeValue (interPacketInterval));
+    client.SetAttribute ("PacketSize", UintegerValue (MaxPacketSize));
+    apps = client.Install (n.Get (0));
+    apps.Start (Seconds (2.0));
+    apps.Stop (Seconds (10.0));
+
+    Simulator::Run ();
+    Simulator::Destroy ();
+
+    if ((server.GetServer ()->GetLost () != 0)
+        || (server.GetServer ()->GetReceived () != 8))
+      {
+        return true; // there was an error
+      }
+    return false;
+
+}
+
+/**
+ * Test that all the udp packets generated by an udpTraceClient application are
+ * correctly received by an udpServer application
+ */
+
+class UdpTraceClientServerTestCase: public TestCase
+{
+public:
+  UdpTraceClientServerTestCase ();
+  virtual ~UdpTraceClientServerTestCase ();
+
+private:
+  virtual bool DoRun (void);
+
+};
+
+UdpTraceClientServerTestCase::UdpTraceClientServerTestCase () :
+  TestCase ("Test that all the udp packets generated by an udpTraceClient application are correctly received by an udpServer application")
+{
+}
+
+UdpTraceClientServerTestCase::~UdpTraceClientServerTestCase ()
+{
+}
+
+bool UdpTraceClientServerTestCase::DoRun (void)
+{
+
+
+  NodeContainer n;
+  n.Create (2);
+
+  InternetStackHelper internet;
+  internet.Install (n);
+
+
+  CsmaHelper csma;
+  csma.SetChannelAttribute ("DataRate", DataRateValue (DataRate(5000000)));
+  csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
+  csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
+  NetDeviceContainer d = csma.Install (n);
+
+  Ipv4AddressHelper ipv4;
+  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
+  Ipv4InterfaceContainer i = ipv4.Assign (d);
+
+  uint16_t port = 4000;
+  UdpServerHelper server (port);
+  ApplicationContainer apps = server.Install (n.Get(1));
+  apps.Start (Seconds (1.0));
+  apps.Stop (Seconds (10.0));
+
+  uint32_t MaxPacketSize = 1400;
+  UdpTraceClientHelper client (i.GetAddress (1), port,"");
+  client.SetAttribute ("MaxPacketSize", UintegerValue (MaxPacketSize));
+  apps = client.Install (n.Get (0));
+  apps.Start (Seconds (2.0));
+  apps.Stop (Seconds (10.0));
+
+  Simulator::Run ();
+  Simulator::Destroy ();
+
+  if ((server.GetServer ()->GetLost () != 0)||
+      (server.GetServer ()->GetReceived () != 247))
+    {
+      return true; // there was an error
+    }
+
+  return false;
+}
+
+
+/**
+ * Test that all the PacketLossCounter class checks loss correctly in different cases
+ */
+
+class PacketLossCounterTestCase: public TestCase
+{
+public:
+  PacketLossCounterTestCase ();
+  virtual ~PacketLossCounterTestCase ();
+
+private:
+  virtual bool DoRun (void);
+
+};
+
+PacketLossCounterTestCase::PacketLossCounterTestCase () :
+  TestCase ("Test that all the PacketLossCounter class checks loss correctly in different cases")
+{
+}
+
+PacketLossCounterTestCase::~PacketLossCounterTestCase ()
+{
+}
+
+bool PacketLossCounterTestCase::DoRun (void)
+{
+  PacketLossCounter lossCounter(32);
+  for (uint32_t i=0;i<64;i++)
+    {
+      lossCounter.NotifyReceived(i);
+    }
+
+  if (lossCounter.GetLost()!=0) // Check that 0 packets are lost
+    {
+      return true;
+    }
+  for (uint32_t i=65;i<128;i++) // drop (1) seqNum 64
+    {
+      lossCounter.NotifyReceived(i);
+    }
+  if (lossCounter.GetLost()!=1) //chek that 1 packet is lost
+    {
+      return true;
+    }
+  for (uint32_t i=134;i<200;i++) // drop seqNum 128,129,130,131,132,133
+    {
+      lossCounter.NotifyReceived(i);
+    }
+  if (lossCounter.GetLost()!=7) //chek that 7 (6+1) packet are lost
+    {
+      return true;
+    }
+  // reordering without loss
+  lossCounter.NotifyReceived(205);
+  lossCounter.NotifyReceived(206);
+  lossCounter.NotifyReceived(207);
+  lossCounter.NotifyReceived(200);
+  lossCounter.NotifyReceived(201);
+  lossCounter.NotifyReceived(202);
+  lossCounter.NotifyReceived(203);
+  lossCounter.NotifyReceived(204);
+  for (uint32_t i=205;i<250;i++)
+    {
+      lossCounter.NotifyReceived(i);
+    }
+  if (lossCounter.GetLost()!=7)
+    {
+      return true;
+    }
+
+  // reordering with loss
+  lossCounter.NotifyReceived(255);
+  // drop (2) seqNum 250, 251
+  lossCounter.NotifyReceived(252);
+  lossCounter.NotifyReceived(253);
+  lossCounter.NotifyReceived(254);
+  for (uint32_t i=256;i<300;i++)
+    {
+      lossCounter.NotifyReceived(i);
+    }
+  if (lossCounter.GetLost()!=9) //chek that 7 (6+1+2) packet are lost
+    {
+      return true;
+    }
+
+
+  return false;
+
+}
+class UdpClientServerTestSuite: public TestSuite
+{
+public:
+  UdpClientServerTestSuite ();
+};
+
+UdpClientServerTestSuite::UdpClientServerTestSuite () :
+  TestSuite ("udp-client-server", UNIT)
+{
+  AddTestCase (new UdpTraceClientServerTestCase);
+  AddTestCase (new UdpClientServerTestCase);
+  AddTestCase (new PacketLossCounterTestCase);
+}
+
+UdpClientServerTestSuite udpClientServerTestSuite;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,155 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ */
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "udp-client.h"
+#include "seq-ts-header.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpClient");
+NS_OBJECT_ENSURE_REGISTERED ( UdpClient);
+
+TypeId
+UdpClient::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpClient")
+    .SetParent<Application> ()
+    .AddConstructor<UdpClient> ()
+    .AddAttribute ("MaxPackets",
+                   "The maximum number of packets the application will send",
+                   UintegerValue (100),
+                   MakeUintegerAccessor (&UdpClient::m_count),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("Interval",
+                   "The time to wait between packets", TimeValue (Seconds (1.0)),
+                   MakeTimeAccessor (&UdpClient::m_interval),
+                   MakeTimeChecker ())
+    .AddAttribute (
+                   "RemoteAddress",
+                   "The destination Ipv4Address of the outbound packets",
+                   Ipv4AddressValue (),
+                   MakeIpv4AddressAccessor (&UdpClient::m_peerAddress),
+                   MakeIpv4AddressChecker ())
+    .AddAttribute ("RemotePort", "The destination port of the outbound packets",
+                   UintegerValue (100),
+                   MakeUintegerAccessor (&UdpClient::m_peerPort),
+                   MakeUintegerChecker<uint16_t> ())
+    .AddAttribute ("PacketSize",
+                   "Size of packets generated. The minimum packet size is 12 bytes which is the size of the header carrying the sequence number and the time stamp.",
+                   UintegerValue (1024),
+                   MakeUintegerAccessor (&UdpClient::m_size),
+                   MakeUintegerChecker<uint32_t> (12,1500))
+    ;
+  return tid;
+}
+
+UdpClient::UdpClient ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_sent = 0;
+  m_socket = 0;
+  m_sendEvent = EventId ();
+}
+
+UdpClient::~UdpClient ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+UdpClient::SetRemote (Ipv4Address ip, uint16_t port)
+{
+  m_peerAddress = ip;
+  m_peerPort = port;
+}
+
+void
+UdpClient::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Application::DoDispose ();
+}
+
+void
+UdpClient::StartApplication (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_socket == 0)
+    {
+      TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+      m_socket = Socket::CreateSocket (GetNode (), tid);
+      m_socket->Bind ();
+      m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+    }
+
+  m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+  m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpClient::Send, this);
+}
+
+void
+UdpClient::StopApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Simulator::Cancel (m_sendEvent);
+}
+
+void
+UdpClient::Send (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  NS_ASSERT (m_sendEvent.IsExpired ());
+  SeqTsHeader seqTs;
+  seqTs.SetSeq (m_sent);
+  Ptr<Packet> p = Create<Packet> (m_size-(8+4)); // 8+4 : the size of the seqTs header
+  p->AddHeader (seqTs);
+
+  if ((m_socket->Send (p)) >= 0)
+    {
+      ++m_sent;
+     NS_LOG_INFO ("TraceDelay TX " << m_size << " bytes to "
+                  << m_peerAddress << " Uid: " << p->GetUid ()
+                  << " Time: " << (Simulator::Now ()).GetSeconds ());
+
+    }
+  else
+    {
+      NS_LOG_INFO ("Error while sending " << m_size << " bytes to "
+                   << m_peerAddress);
+    }
+
+  if (m_sent < m_count)
+    {
+      m_sendEvent = Simulator::Schedule (m_interval, &UdpClient::Send, this);
+    }
+}
+
+} // Namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-client.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,85 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ *
+ */
+
+#ifndef __UDP_CLIENT_H__
+#define __UDP_CLIENT_H__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpClient
+ * \brief A Udp client. Sends UDP packet carrying sequence number and time stamp
+ *  in their payloads
+ *
+ */
+class UdpClient : public Application
+{
+public:
+  static TypeId
+  GetTypeId (void);
+
+  UdpClient ();
+
+  virtual ~UdpClient ();
+
+  /**
+   * \brief set the remote address and port
+   * \param ip remote IP address
+   * \param port remote port
+   */
+  void SetRemote (Ipv4Address ip, uint16_t port);
+
+protected:
+  virtual void DoDispose (void);
+
+private:
+
+  virtual void StartApplication (void);
+  virtual void StopApplication (void);
+
+  void ScheduleTransmit (Time dt);
+  void Send (void);
+
+  uint32_t m_count;
+  Time m_interval;
+  uint32_t m_size;
+
+  uint32_t m_sent;
+  Ptr<Socket> m_socket;
+  Ipv4Address m_peerAddress;
+  uint16_t m_peerPort;
+  EventId m_sendEvent;
+
+};
+
+} // namespace ns3
+
+#endif // __UDP_CLIENT_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-server.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,164 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ */
+
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "packet-loss-counter.h"
+
+#include "seq-ts-header.h"
+#include "udp-server.h"
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpServer");
+NS_OBJECT_ENSURE_REGISTERED ( UdpServer);
+
+
+TypeId
+UdpServer::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpServer")
+    .SetParent<Application> ()
+    .AddConstructor<UdpServer> ()
+    .AddAttribute ("Port",
+                   "Port on which we listen for incoming packets.",
+                   UintegerValue (100),
+                   MakeUintegerAccessor (&UdpServer::m_port),
+                   MakeUintegerChecker<uint16_t> ())
+    .AddAttribute ("PacketWindowSize",
+                   "The size of the window used to compute the packet loss. This value should be a multiple of 8.",
+                   UintegerValue (32),
+                   MakeUintegerAccessor (&UdpServer::GetPacketWindowSize,
+                                         &UdpServer::SetPacketWindowSize),
+                   MakeUintegerChecker<uint16_t> (8,256))
+    ;
+  return tid;
+}
+
+UdpServer::UdpServer ()
+ : m_lossCounter (0)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_received=0;
+}
+
+UdpServer::~UdpServer ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+uint16_t
+UdpServer::GetPacketWindowSize () const
+{
+  return m_lossCounter.GetBitMapSize ();
+}
+
+void
+UdpServer::SetPacketWindowSize (uint16_t size)
+{
+  m_lossCounter.SetBitMapSize (size);
+}
+
+uint32_t
+UdpServer::GetLost (void) const
+{
+  return m_lossCounter.GetLost ();
+}
+
+uint32_t
+UdpServer::GetReceived (void) const
+{
+
+  return m_received;
+
+}
+
+void
+UdpServer::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Application::DoDispose ();
+}
+
+void
+UdpServer::StartApplication (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_socket == 0)
+    {
+      TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+      m_socket = Socket::CreateSocket (GetNode (), tid);
+      InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (),
+                                                   m_port);
+      m_socket->Bind (local);
+    }
+
+  m_socket->SetRecvCallback (MakeCallback (&UdpServer::HandleRead, this));
+
+}
+
+void
+UdpServer::StopApplication ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  if (m_socket != 0)
+    {
+      m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+    }
+}
+
+void
+UdpServer::HandleRead (Ptr<Socket> socket)
+{
+  Ptr<Packet> packet;
+  Address from;
+  while (packet = socket->RecvFrom (from))
+    {
+      if (packet->GetSize () > 0)
+        {
+          SeqTsHeader seqTs;
+          packet->RemoveHeader (seqTs);
+          Time delay = Simulator::Now () - seqTs.GetTs ();
+          uint32_t currentSequenceNumber = seqTs.GetSeq ();
+          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: " << delay) ;
+
+          m_lossCounter.NotifyReceived (currentSequenceNumber);
+          m_received++;
+        }
+    }
+}
+
+} // Namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-server.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,94 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007,2008,2009 INRIA, UDCAST
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                      <amine.ismail@udcast.com>
+ *
+ */
+
+#ifndef __UDP_SERVER_H__
+#define __UDP_SERVER_H__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/address.h"
+#include "packet-loss-counter.h"
+namespace ns3 {
+/**
+ * \ingroup applications
+ * \defgroup udpclientserver UdpClientServer
+ */
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpServer
+ * \brief A Udp server. Receives UDP packets from a remote host. UDP packets
+ * carry a 32bits sequence number followed by a 64bits time stamp in their
+ * payloads. The application uses, the sequence number to determine if a packet
+ * is lost, and the time stamp to compute the delay
+ */
+class UdpServer : public Application
+{
+public:
+  static TypeId GetTypeId (void);
+  UdpServer ();
+  virtual ~UdpServer ();
+  /**
+   * returns the number of lost packets
+   * \return the number of lost packets
+   */
+  uint32_t GetLost (void) const;
+
+  /**
+   * \brief returns the number of received packets
+   * \return the number of received packets
+   */
+  uint32_t GetReceived (void) const;
+
+  /**
+   * \return the size of the window used for checking loss.
+   */
+  uint16_t GetPacketWindowSize () const;
+
+  /**
+   * \brief Set the size of the window used for checking loss. This value should
+   *  be a multiple of 8
+   * \param size the size of the window used for checking loss. This value should
+   *  be a multiple of 8
+   */
+  void SetPacketWindowSize (uint16_t size);
+protected:
+  virtual void DoDispose (void);
+
+private:
+
+  virtual void StartApplication (void);
+  virtual void StopApplication (void);
+
+  void HandleRead (Ptr<Socket> socket);
+
+  uint16_t m_port;
+  Ptr<Socket> m_socket;
+  Address m_local;
+  uint32_t m_received;
+  PacketLossCounter m_lossCounter;
+};
+
+} // namespace ns3
+
+#endif // __UDP_SERVER_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-trace-client.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,292 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                              <amine.ismail@udcast.com>
+ */
+#include "ns3/log.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/nstime.h"
+#include "ns3/inet-socket-address.h"
+#include "ns3/socket.h"
+#include "ns3/simulator.h"
+#include "ns3/socket-factory.h"
+#include "ns3/packet.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+#include "seq-ts-header.h"
+#include "udp-trace-client.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <fstream>
+
+namespace ns3 {
+
+NS_LOG_COMPONENT_DEFINE ("UdpTraceClient");
+NS_OBJECT_ENSURE_REGISTERED ( UdpTraceClient);
+
+struct UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
+  {0, 534, 'I'},
+  {40, 1542, 'P'},
+  {120, 134, 'B'},
+  {80, 390, 'B'},
+  {240, 765, 'P'},
+  {160, 407, 'B'},
+  {200, 504, 'B'},
+  {360, 903, 'P'},
+  {280, 421, 'B'},
+  {320, 587, 'B'}
+};
+
+TypeId
+UdpTraceClient::GetTypeId (void)
+{
+  static TypeId tid = TypeId ("ns3::UdpTraceClient")
+    .SetParent<Application> ()
+    .AddConstructor<UdpTraceClient> ()
+    .AddAttribute ("RemoteAddress",
+                   "The destination Ipv4Address of the outbound packets",
+                   Ipv4AddressValue (),
+                   MakeIpv4AddressAccessor (&UdpTraceClient::m_peerAddress),
+                   MakeIpv4AddressChecker ())
+    .AddAttribute ("RemotePort",
+                   "The destination port of the outbound packets",
+                   UintegerValue (100),
+                   MakeUintegerAccessor (&UdpTraceClient::m_peerPort),
+                   MakeUintegerChecker<uint16_t> ())
+    .AddAttribute ("MaxPacketSize",
+                   "The maximum size of a packet.",
+                   UintegerValue (1024),
+                   MakeUintegerAccessor (&UdpTraceClient::m_maxPacketSize),
+                   MakeUintegerChecker<uint32_t> ())
+    .AddAttribute ("TraceFilename",
+                   "Name of file to load a trace from. By default, uses a hardcoded trace.",
+                   StringValue (""),
+                   MakeStringAccessor (&UdpTraceClient::SetTraceFile),
+                   MakeStringChecker ())
+
+    ;
+  return tid;
+}
+
+UdpTraceClient::UdpTraceClient ()
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_sent = 0;
+  m_socket = 0;
+  m_sendEvent = EventId ();
+  m_maxPacketSize = 1400;
+}
+
+UdpTraceClient::UdpTraceClient (Ipv4Address ip, uint16_t port,
+                                        char *traceFile)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  m_sent = 0;
+  m_socket = 0;
+  m_sendEvent = EventId ();
+  m_peerAddress = ip;
+  m_peerPort = port;
+  m_currentEntry = 0;
+  m_maxPacketSize = 1400;
+  if (traceFile != NULL)
+    {
+      SetTraceFile (traceFile);
+    }
+}
+
+UdpTraceClient::~UdpTraceClient ()
+{
+  m_entries.clear ();
+  NS_LOG_FUNCTION_NOARGS ();
+}
+
+void
+UdpTraceClient::SetRemote (Ipv4Address ip, uint16_t port)
+{
+  m_entries.clear ();
+  m_peerAddress = ip;
+  m_peerPort = port;
+}
+
+void
+UdpTraceClient::SetTraceFile (std::string traceFile)
+{
+  if (traceFile == "")
+    {
+      LoadDefaultTrace ();
+    }
+  else
+    {
+      LoadTrace (traceFile);
+    }
+}
+
+void
+UdpTraceClient::SetMaxPacketSize (uint16_t maxPacketSize){
+  m_maxPacketSize = maxPacketSize;
+}
+
+
+uint16_t UdpTraceClient::GetMaxPacketSize (void){
+  return m_maxPacketSize;
+}
+
+
+void
+UdpTraceClient::DoDispose (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+  Application::DoDispose ();
+}
+
+void
+UdpTraceClient::LoadTrace (std::string filename)
+{
+  uint32_t time, index, prevTime = 0;
+  uint16_t size;
+  char frameType;
+  TraceEntry entry;
+  std::ifstream ifTraceFile;
+  ifTraceFile.open (filename.c_str (), std::ifstream::in);
+  m_entries.clear ();
+  if (!ifTraceFile.good ())
+    {
+      LoadDefaultTrace ();
+    }
+  while (ifTraceFile.good ())
+    {
+      ifTraceFile >> index >> frameType >> time >> size;
+      if (frameType == 'B')
+        {
+          entry.timeToSend = 0;
+        }
+      else
+        {
+          entry.timeToSend = time - prevTime;
+          prevTime = time;
+        }
+      entry.packetSize = size;
+      entry.frameType = frameType;
+      m_entries.push_back (entry);
+    }
+  ifTraceFile.close ();
+  m_currentEntry = 0;
+}
+
+void
+UdpTraceClient::LoadDefaultTrace (void)
+{
+  uint32_t prevTime = 0;
+  for (uint32_t i = 0; i < (sizeof (g_defaultEntries) / sizeof (struct TraceEntry)); i++)
+    {
+      struct TraceEntry entry = g_defaultEntries[i];
+      if (entry.frameType == 'B')
+        {
+          entry.timeToSend = 0;
+        }
+      else
+        {
+          uint32_t tmp = entry.timeToSend;
+          entry.timeToSend -= prevTime;
+          prevTime = tmp;
+        }
+      m_entries.push_back (entry);
+    }
+  m_currentEntry = 0;
+}
+
+void
+UdpTraceClient::StartApplication (void)
+{
+  NS_LOG_FUNCTION (this);
+
+  if (m_socket == 0)
+    {
+      TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
+      m_socket = Socket::CreateSocket (GetNode (), tid);
+      m_socket->Bind ();
+      m_socket->Connect (InetSocketAddress (m_peerAddress, m_peerPort));
+    }
+  m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
+  m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpTraceClient::Send, this);
+}
+
+void
+UdpTraceClient::StopApplication ()
+{
+  NS_LOG_FUNCTION (this);
+  Simulator::Cancel (m_sendEvent);
+}
+
+void
+UdpTraceClient::SendPacket (uint32_t size)
+{
+  Ptr<Packet> p;
+  uint32_t packetSize;
+  if (size>12)
+    {
+      packetSize = size - 12; // 12 is the size of the SeqTsHeader
+    }
+  else
+    {
+      packetSize = 0;
+    }
+  p = Create<Packet> (packetSize);
+  SeqTsHeader seqTs;
+  seqTs.SetSeq (m_sent);
+  p->AddHeader (seqTs);
+  if ((m_socket->Send (p)) >= 0)
+    {
+      ++m_sent;
+      NS_LOG_INFO ("Sent " << size << " bytes to "
+                   << m_peerAddress);
+    }
+  else
+    {
+      NS_LOG_INFO ("Error while sending " << size << " bytes to "
+                   << m_peerAddress);
+    }
+}
+
+void
+UdpTraceClient::Send (void)
+{
+  NS_LOG_FUNCTION_NOARGS ();
+
+  NS_ASSERT (m_sendEvent.IsExpired ());
+  Ptr<Packet> p;
+  struct TraceEntry *entry = &m_entries[m_currentEntry];
+  do
+    {
+      for (int i = 0; i < entry->packetSize / m_maxPacketSize; i++)
+        {
+          SendPacket (m_maxPacketSize);
+        }
+
+      uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
+      SendPacket (sizetosend);
+
+      m_currentEntry++;
+      m_currentEntry %= m_entries.size ();
+      entry = &m_entries[m_currentEntry];
+    }
+  while (entry->timeToSend == 0);
+  m_sendEvent = Simulator::Schedule (MilliSeconds (entry->timeToSend), &UdpTraceClient::Send, this);
+}
+
+} // Namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/udp-trace-client.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,135 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ *  Copyright (c) 2007,2008, 2009 INRIA, UDcast
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ *                              <amine.ismail@udcast.com>
+ */
+
+#ifndef __UDP_TRACE_CLIENT__
+#define __UDP_TRACE_CLIENT__
+
+#include "ns3/application.h"
+#include "ns3/event-id.h"
+#include "ns3/ptr.h"
+#include "ns3/ipv4-address.h"
+#include <vector>
+namespace ns3 {
+
+class Socket;
+class Packet;
+
+/**
+ * \ingroup udpclientserver
+ * \class UdpTraceClient
+ * \brief A trace based streamer
+ *
+ * sends udp packets based on a trace file of an MPEG4 stream
+ * trace files could be downloaded form :
+ * http://www.tkn.tu-berlin.de/research/trace/ltvt.html (the 2 first lines of
+ * the file should be removed)
+ * A valid trace file is a file with 4 columns:
+ * -1- the first one represents the frame index
+ * -2- the second one indicates the type of the frame: I, P or B
+ * -3- the third one indicates the time on which the frame was generated by the encoder
+ * -4- the fourth one indicates the frame size in byte
+ * if no valid MPEG4 trace file is provided to the application the trace from
+ * g_defaultEntries array will be loaded.
+ */
+class UdpTraceClient : public Application
+{
+public:
+  static TypeId
+  GetTypeId (void);
+  /**
+   * \brief creates a traceBasedStreamer application
+   */
+  UdpTraceClient ();
+
+  /**
+   * \brief creates a traceBasedStreamer application
+   * \param dataSize ip the destination ip address to which the stream will be sent
+   * \param port the destination udp port to which the stream will be sent
+   * \param traceFile a path to an MPEG4 trace file formatted as follows:
+   *  FrameNo Frametype   Time[ms]    Length [byte]
+   *  FrameNo Frametype   Time[ms]    Length [byte]
+   *  ...
+   *
+   *
+   */
+
+  UdpTraceClient (Ipv4Address ip, uint16_t port, char *traceFile);
+  ~UdpTraceClient ();
+
+  /**
+   * \brief set the destination IP address and port
+   * \param ip the destination ip address to which the stream will be sent
+   * \param port the destination udp port to which the stream will be sent
+   */
+  void SetRemote (Ipv4Address ip, uint16_t port);
+
+  /**
+   * \brief set the trace file to be used by the application
+   * \param traceFile a path to an MPEG4 trace file formatted as follows:
+   *  Frame No Frametype   Time[ms]    Length [byte]
+   *  Frame No Frametype   Time[ms]    Length [byte]
+   *  ...
+   */
+  void SetTraceFile (std::string filename);
+
+  /**
+   * \return the maximum packet size
+   */
+  uint16_t GetMaxPacketSize(void);
+
+  /**
+   * \param maxPacketSize The maximum packet size
+   */
+  void SetMaxPacketSize(uint16_t maxPacketSize);
+
+protected:
+  virtual void DoDispose (void);
+
+private:
+  void LoadTrace (std::string filename);
+  void LoadDefaultTrace (void);
+  virtual void StartApplication (void);
+  virtual void StopApplication (void);
+  void ScheduleTransmit (Time dt);
+  void Send (void);
+  void SendPacket (uint32_t size);
+
+
+  struct TraceEntry
+  {
+    uint32_t timeToSend;
+    uint16_t packetSize;
+    char frameType;
+  };
+  uint32_t m_sent;
+  Ptr<Socket> m_socket;
+  Ipv4Address m_peerAddress;
+  uint16_t m_peerPort;
+  EventId m_sendEvent;
+  std::vector<struct TraceEntry> m_entries;
+  uint32_t m_currentEntry;
+  static struct TraceEntry g_defaultEntries[];
+  uint16_t m_maxPacketSize;
+};
+
+} // namespace ns3
+
+#endif // __UDP_TRACE_CLIENT__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/waf	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,1 @@
+exec "`dirname "$0"`"/../../../waf "$@"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/applications/udp-client-server/wscript	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,21 @@
+## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def build(bld):
+    module = bld.create_ns3_module('udp-client-server', ['internet-stack'])
+    module.source = [
+        'udp-client.cc',
+        'udp-server.cc',
+        'seq-ts-header.cc',
+        'udp-trace-client.cc',
+        'udp-client-server-test.cc',
+        'packet-loss-counter.cc',
+        ]
+    headers = bld.new_task_gen('ns3header')
+    headers.module = 'udp-client-server'
+    headers.source = [
+        'udp-client.h',
+        'udp-server.h',
+        'udp-trace-client.h',
+        'packet-loss-counter.h',
+        ]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-client-server-helper.cc	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,127 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ */
+#include "udp-client-server-helper.h"
+#include "ns3/udp-server.h"
+#include "ns3/udp-client.h"
+#include "ns3/udp-trace-client.h"
+#include "ns3/uinteger.h"
+#include "ns3/string.h"
+
+namespace ns3 {
+
+UdpServerHelper::UdpServerHelper ()
+{}
+
+UdpServerHelper::UdpServerHelper (uint16_t port)
+{
+  m_factory.SetTypeId (UdpServer::GetTypeId ());
+  SetAttribute ("Port", UintegerValue (port));
+}
+
+void
+UdpServerHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+  m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpServerHelper::Install (NodeContainer c)
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+
+      m_server = m_factory.Create<UdpServer> ();
+      node->AddApplication (m_server);
+      apps.Add (m_server);
+
+    }
+  return apps;
+}
+
+Ptr<UdpServer>
+UdpServerHelper::GetServer (void)
+{
+  return m_server;
+}
+
+UdpClientHelper::UdpClientHelper ()
+{}
+
+UdpClientHelper::UdpClientHelper (Ipv4Address address, uint16_t port)
+{
+  m_factory.SetTypeId (UdpClient::GetTypeId ());
+  SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+  SetAttribute ("RemotePort", UintegerValue (port));
+}
+
+void
+UdpClientHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+  m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpClientHelper::Install (NodeContainer c)
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<UdpClient> client = m_factory.Create<UdpClient> ();
+      node->AddApplication (client);
+      apps.Add (client);
+    }
+  return apps;
+}
+
+UdpTraceClientHelper::UdpTraceClientHelper ()
+{}
+
+UdpTraceClientHelper::UdpTraceClientHelper (Ipv4Address address, uint16_t port, std::string filename)
+{
+  m_factory.SetTypeId (UdpTraceClient::GetTypeId ());
+  SetAttribute ("RemoteAddress", Ipv4AddressValue (address));
+  SetAttribute ("RemotePort", UintegerValue (port));
+  SetAttribute ("TraceFilename", StringValue (filename));
+}
+
+void
+UdpTraceClientHelper::SetAttribute (std::string name, const AttributeValue &value)
+{
+  m_factory.Set (name, value);
+}
+
+ApplicationContainer
+UdpTraceClientHelper::Install (NodeContainer c)
+{
+  ApplicationContainer apps;
+  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
+    {
+      Ptr<Node> node = *i;
+      Ptr<UdpTraceClient> client = m_factory.Create<UdpTraceClient> ();
+      node->AddApplication (client);
+      apps.Add (client);
+    }
+  return apps;
+}
+
+} // namespace ns3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/helper/udp-client-server-helper.h	Fri Nov 27 17:06:45 2009 +0100
@@ -0,0 +1,178 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2008 INRIA
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
+ */
+#ifndef UDP_CLIENT_SERVER_HELPER_H
+#define UDP_CLIENT_SERVER_HELPER_H
+
+#include <stdint.h>
+#include "application-container.h"
+#include "node-container.h"
+#include "ns3/object-factory.h"
+#include "ns3/ipv4-address.h"
+#include "ns3/udp-server.h"
+#include "ns3/udp-client.h"
+namespace ns3 {
+  /**
+   * \brief Create a server application which waits for input udp packets
+   *        and uses the information carried into their payload to compute
+   *        delay and to determine if some packets are lost.
+   */
+class UdpServerHelper
+{
+public:
+   /**
+    * Create UdpServerHelper which will make life easier for people trying
+    * to set up simulations with udp-client-server application.
+    *
+    */
+  UdpServerHelper ();
+
+   /**
+    * Create UdpServerHelper which will make life easier for people trying
+    * to set up simulations with udp-client-server application.
+    *
+    * \param port The port the server will wait on for incoming packets
+    */
+  UdpServerHelper (uint16_t port);
+
+    /**
+     * Record an attribute to be set in each Application after it is is created.
+     *
+     * \param name the name of the attribute to set
+     * \param value the value of the attribute to set
+     */
+  void SetAttribute (std::string name, const AttributeValue &value);
+
+  /**
+   * Create one udp server application on each of the Nodes in the
+   * NodeContainer.
+   *
+   * \param c The nodes on which to create the Applications.  The nodes
+   *          are specified by a NodeContainer.
+   * \returns The applications created, one Application per Node in the
+   *          NodeContainer.
+   */
+  ApplicationContainer Install (NodeContainer c);
+  Ptr<UdpServer> GetServer(void);
+private:
+  ObjectFactory m_factory;
+  Ptr<UdpServer> m_server;
+};
+
+/**
+ * \brief Create a client application which sends udp packets carrying
+ *  a 32bit sequence numbre and a 64 bit time stamp.
+ *
+ */
+class UdpClientHelper
+{
+
+public:
+  /**
+   * Create UdpClientHelper which will make life easier for people trying
+   * to set up simulations with udp-client-server.
+   *
+   */
+  UdpClientHelper ();
+
+   /**
+    *  Create UdpClientHelper which will make life easier for people trying
+    * to set up simulations with udp-client-server.
+    *
+    * \param ip The IP address of the remote udp server
+    * \param port The port number of the remote udp server
+    */
+
+  UdpClientHelper (Ipv4Address ip, uint16_t port);
+
+  /**
+   * Record an attribute to be set in each Application after it is is created.
+   *
+   * \param name the name of the attribute to set
+   * \param value the value of the attribute to set
+   */
+  void SetAttribute (std::string name, const AttributeValue &value);
+
+  /**
+     * \param c the nodes
+     *
+     * Create one udp client application on each of the input nodes
+     *
+     * \returns the applications created, one application per input node.
+     */
+  ApplicationContainer Install (NodeContainer c);
+
+private:
+  ObjectFactory m_factory;
+};
+ /**
+  * Create udpTraceClient application which sends udp packets based on a trace
+  * file of an MPEG4 stream. Trace files could be downloaded form :
+  * http://www.tkn.tu-berlin.de/research/trace/ltvt.html (the 2 first lines of
+  * the file should be removed)
+  * A valid trace file is a file with 4 columns:
+  * -1- the first one represents the frame index
+  * -2- the second one indicates the type of the frame: I, P or B
+  * -3- the third one indicates the time on which the frame was generated by the encoder
+  * -4- the fourth one indicates the frame size in byte
+*/
+class UdpTraceClientHelper
+{
+public:
+  /**
+   * Create UdpTraceClientHelper which will make life easier for people trying
+   * to set up simulations with udp-client-server.
+   *
+   */
+  UdpTraceClientHelper ();
+
+  /**
+   * Create UdpTraceClientHelper which will make life easier for people trying
+   * to set up simulations with udp-client-server.
+   *
+   * \param ip The IP address of the remote udp server
+   * \param port The port number of the remote udp server
+   * \param filename the file from which packet traces will be loaded
+   */
+  UdpTraceClientHelper (Ipv4Address ip, uint16_t port, std::string filename);
+
+  /**
+    * Record an attribute to be set in each Application after it is is created.
+    *
+    * \param name the name of the attribute to set
+    * \param value the value of the attribute to set
+    */
+  void SetAttribute (std::string name, const AttributeValue &value);
+
+  /**
+    * \param c the nodes
+    *
+    * Create one udp trace client application on each of the input nodes
+    *
+    * \returns the applications created, one application per input node.
+    */
+  ApplicationContainer Install (NodeContainer c);
+
+private:
+  ObjectFactory m_factory;
+};
+
+} // namespace ns3
+
+#endif /* UDP_CLIENT_SERVER_H */
--- a/src/helper/wscript	Thu Nov 26 14:53:53 2009 +0100
+++ b/src/helper/wscript	Fri Nov 27 17:06:45 2009 +0100
@@ -47,6 +47,7 @@
         'point-to-point-grid-helper.cc',
         'point-to-point-star-helper.cc',
         'csma-star-helper.cc',
+        'udp-client-server-helper.cc',
         ]
 
     headers = bld.new_task_gen('ns3header')
@@ -97,6 +98,7 @@
         'point-to-point-grid-helper.h',
         'point-to-point-star-helper.h',
         'csma-star-helper.h',
+        'udp-client-server-helper.h',
         ]
 
     env = bld.env_of_name('default')
--- a/src/wscript	Thu Nov 26 14:53:53 2009 +0100
+++ b/src/wscript	Fri Nov 27 17:06:45 2009 +0100
@@ -47,6 +47,7 @@
     'test/ns3tcp',
     'test/ns3wifi',
     'contrib/flow-monitor',
+    'applications/udp-client-server',
     )
 
 def set_options(opt):