A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
udp-trace-client.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
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: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
19  * <amine.ismail@udcast.com>
20  */
21 #include "ns3/log.h"
22 #include "ns3/ipv4-address.h"
23 #include "ns3/nstime.h"
24 #include "ns3/inet-socket-address.h"
25 #include "ns3/inet6-socket-address.h"
26 #include "ns3/socket.h"
27 #include "ns3/simulator.h"
28 #include "ns3/socket-factory.h"
29 #include "ns3/packet.h"
30 #include "ns3/uinteger.h"
31 #include "ns3/string.h"
32 #include "seq-ts-header.h"
33 #include "udp-trace-client.h"
34 #include <cstdlib>
35 #include <cstdio>
36 #include <fstream>
37 
38 namespace ns3 {
39 
40 NS_LOG_COMPONENT_DEFINE ("UdpTraceClient");
41 NS_OBJECT_ENSURE_REGISTERED (UdpTraceClient);
42 
43 struct UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
44  { 0, 534, 'I'},
45  { 40, 1542, 'P'},
46  { 120, 134, 'B'},
47  { 80, 390, 'B'},
48  { 240, 765, 'P'},
49  { 160, 407, 'B'},
50  { 200, 504, 'B'},
51  { 360, 903, 'P'},
52  { 280, 421, 'B'},
53  { 320, 587, 'B'}
54 };
55 
56 TypeId
57 UdpTraceClient::GetTypeId (void)
58 {
59  static TypeId tid = TypeId ("ns3::UdpTraceClient")
61  .AddConstructor<UdpTraceClient> ()
62  .AddAttribute ("RemoteAddress",
63  "The destination Address of the outbound packets",
64  AddressValue (),
65  MakeAddressAccessor (&UdpTraceClient::m_peerAddress),
66  MakeAddressChecker ())
67  .AddAttribute ("RemotePort",
68  "The destination port of the outbound packets",
69  UintegerValue (100),
70  MakeUintegerAccessor (&UdpTraceClient::m_peerPort),
71  MakeUintegerChecker<uint16_t> ())
72  .AddAttribute ("MaxPacketSize",
73  "The maximum size of a packet.",
74  UintegerValue (1024),
75  MakeUintegerAccessor (&UdpTraceClient::m_maxPacketSize),
76  MakeUintegerChecker<uint32_t> ())
77  .AddAttribute ("TraceFilename",
78  "Name of file to load a trace from. By default, uses a hardcoded trace.",
79  StringValue (""),
80  MakeStringAccessor (&UdpTraceClient::SetTraceFile),
81  MakeStringChecker ())
82 
83  ;
84  return tid;
85 }
86 
88 {
89  NS_LOG_FUNCTION (this);
90  m_sent = 0;
91  m_socket = 0;
92  m_sendEvent = EventId ();
93  m_maxPacketSize = 1400;
94 }
95 
97  char *traceFile)
98 {
99  NS_LOG_FUNCTION (this);
100  m_sent = 0;
101  m_socket = 0;
102  m_sendEvent = EventId ();
103  m_peerAddress = ip;
104  m_peerPort = port;
105  m_currentEntry = 0;
106  m_maxPacketSize = 1400;
107  if (traceFile != NULL)
108  {
109  SetTraceFile (traceFile);
110  }
111 }
112 
113 UdpTraceClient::~UdpTraceClient ()
114 {
115  NS_LOG_FUNCTION (this);
116  m_entries.clear ();
117 }
118 
119 void
121 {
122  NS_LOG_FUNCTION (this << ip << port);
123  m_entries.clear ();
124  m_peerAddress = ip;
125  m_peerPort = port;
126 }
127 
128 void
129 UdpTraceClient::SetRemote (Ipv4Address ip, uint16_t port)
130 {
131  NS_LOG_FUNCTION (this << ip << port);
132  m_entries.clear ();
133  m_peerAddress = Address (ip);
134  m_peerPort = port;
135 }
136 
137 void
138 UdpTraceClient::SetRemote (Ipv6Address ip, uint16_t port)
139 {
140  NS_LOG_FUNCTION (this << ip << port);
141  m_entries.clear ();
142  m_peerAddress = Address (ip);
143  m_peerPort = port;
144 }
145 
146 void
147 UdpTraceClient::SetTraceFile (std::string traceFile)
148 {
149  NS_LOG_FUNCTION (this << traceFile);
150  if (traceFile == "")
151  {
152  LoadDefaultTrace ();
153  }
154  else
155  {
156  LoadTrace (traceFile);
157  }
158 }
159 
160 void
161 UdpTraceClient::SetMaxPacketSize (uint16_t maxPacketSize)
162 {
163  NS_LOG_FUNCTION (this << maxPacketSize);
164  m_maxPacketSize = maxPacketSize;
165 }
166 
167 
169 {
170  NS_LOG_FUNCTION (this);
171  return m_maxPacketSize;
172 }
173 
174 
175 void
177 {
178  NS_LOG_FUNCTION (this);
180 }
181 
182 void
183 UdpTraceClient::LoadTrace (std::string filename)
184 {
185  NS_LOG_FUNCTION (this << filename);
186  uint32_t time, index, prevTime = 0;
187  uint16_t size;
188  char frameType;
189  TraceEntry entry;
190  std::ifstream ifTraceFile;
191  ifTraceFile.open (filename.c_str (), std::ifstream::in);
192  m_entries.clear ();
193  if (!ifTraceFile.good ())
194  {
195  LoadDefaultTrace ();
196  }
197  while (ifTraceFile.good ())
198  {
199  ifTraceFile >> index >> frameType >> time >> size;
200  if (frameType == 'B')
201  {
202  entry.timeToSend = 0;
203  }
204  else
205  {
206  entry.timeToSend = time - prevTime;
207  prevTime = time;
208  }
209  entry.packetSize = size;
210  entry.frameType = frameType;
211  m_entries.push_back (entry);
212  }
213  ifTraceFile.close ();
214  m_currentEntry = 0;
215 }
216 
217 void
218 UdpTraceClient::LoadDefaultTrace (void)
219 {
220  NS_LOG_FUNCTION (this);
221  uint32_t prevTime = 0;
222  for (uint32_t i = 0; i < (sizeof (g_defaultEntries) / sizeof (struct TraceEntry)); i++)
223  {
224  struct TraceEntry entry = g_defaultEntries[i];
225  if (entry.frameType == 'B')
226  {
227  entry.timeToSend = 0;
228  }
229  else
230  {
231  uint32_t tmp = entry.timeToSend;
232  entry.timeToSend -= prevTime;
233  prevTime = tmp;
234  }
235  m_entries.push_back (entry);
236  }
237  m_currentEntry = 0;
238 }
239 
240 void
242 {
243  NS_LOG_FUNCTION (this);
244 
245  if (m_socket == 0)
246  {
247  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
248  m_socket = Socket::CreateSocket (GetNode (), tid);
249  if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
250  {
251  m_socket->Bind ();
252  m_socket->Connect (InetSocketAddress (Ipv4Address::ConvertFrom (m_peerAddress), m_peerPort));
253  }
254  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
255  {
256  m_socket->Bind6 ();
257  m_socket->Connect (Inet6SocketAddress (Ipv6Address::ConvertFrom (m_peerAddress), m_peerPort));
258  }
259  }
260  m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
261  m_sendEvent = Simulator::Schedule (Seconds (0.0), &UdpTraceClient::Send, this);
262 }
263 
264 void
266 {
267  NS_LOG_FUNCTION (this);
268  Simulator::Cancel (m_sendEvent);
269 }
270 
271 void
272 UdpTraceClient::SendPacket (uint32_t size)
273 {
274  NS_LOG_FUNCTION (this << size);
275  Ptr<Packet> p;
276  uint32_t packetSize;
277  if (size>12)
278  {
279  packetSize = size - 12; // 12 is the size of the SeqTsHeader
280  }
281  else
282  {
283  packetSize = 0;
284  }
285  p = Create<Packet> (packetSize);
286  SeqTsHeader seqTs;
287  seqTs.SetSeq (m_sent);
288  p->AddHeader (seqTs);
289 
290  std::stringstream addressString;
291  if (Ipv4Address::IsMatchingType(m_peerAddress) == true)
292  {
293  addressString << Ipv4Address::ConvertFrom (m_peerAddress);
294  }
295  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
296  {
297  addressString << Ipv6Address::ConvertFrom (m_peerAddress);
298  }
299  else
300  {
301  addressString << m_peerAddress;
302  }
303 
304  if ((m_socket->Send (p)) >= 0)
305  {
306  ++m_sent;
307  NS_LOG_INFO ("Sent " << size << " bytes to "
308  << addressString.str ());
309  }
310  else
311  {
312  NS_LOG_INFO ("Error while sending " << size << " bytes to "
313  << addressString.str ());
314  }
315 }
316 
317 void
318 UdpTraceClient::Send (void)
319 {
320  NS_LOG_FUNCTION (this);
321 
322  NS_ASSERT (m_sendEvent.IsExpired ());
323  Ptr<Packet> p;
324  struct TraceEntry *entry = &m_entries[m_currentEntry];
325  do
326  {
327  for (int i = 0; i < entry->packetSize / m_maxPacketSize; i++)
328  {
329  SendPacket (m_maxPacketSize);
330  }
331 
332  uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
333  SendPacket (sizetosend);
334 
335  m_currentEntry++;
336  m_currentEntry %= m_entries.size ();
337  entry = &m_entries[m_currentEntry];
338  }
339  while (entry->timeToSend == 0);
340  m_sendEvent = Simulator::Schedule (MilliSeconds (entry->timeToSend), &UdpTraceClient::Send, this);
341 }
342 
343 } // Namespace ns3
static bool IsMatchingType(const Address &address)
If the Address matches the type.
an Inet address class
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
virtual int Bind6()=0
Allocate a local IPv6 endpoint for this socket.
hold variables of type string
Definition: string.h:19
#define NS_ASSERT(condition)
Definition: assert.h:64
virtual void StartApplication(void)
Application specific startup code.
#define NS_LOG_COMPONENT_DEFINE(name)
Definition: log.h:122
#define NS_LOG_INFO(msg)
Definition: log.h:264
static void Cancel(const EventId &id)
Definition: simulator.cc:267
static EventId Schedule(Time const &time, MEM mem_ptr, OBJ obj)
Definition: simulator.h:820
virtual void StopApplication(void)
Application specific shutdown code.
UdpTraceClient()
creates a traceBasedStreamer application
void SetTraceFile(std::string filename)
set the trace file to be used by the application
a polymophic address class
Definition: address.h:86
The base class for all ns3 applications.
Definition: application.h:61
Hold an unsigned integer type.
Definition: uinteger.h:46
uint16_t GetMaxPacketSize(void)
Ptr< Node > GetNode() const
Definition: application.cc:103
An Inet6 address class.
void SetRecvCallback(Callback< void, Ptr< Socket > >)
Notify application when new data is available to be read.
Definition: socket.cc:127
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
Definition: socket.cc:70
static bool IsMatchingType(const Address &address)
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual void DoDispose(void)
Definition: application.cc:82
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
void SetMaxPacketSize(uint16_t maxPacketSize)
Callback< R > MakeNullCallback(void)
Definition: callback.h:781
A trace based streamer.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
hold objects of type ns3::Address
Time Seconds(double seconds)
create ns3::Time instances in units of seconds.
Definition: nstime.h:586
an identifier for simulation events.
Definition: event-id.h:46
void SetRemote(Address ip, uint16_t port)
set the destination IP address and port
Time MilliSeconds(uint64_t ms)
create ns3::Time instances in units of milliseconds.
Definition: nstime.h:601
static Ipv4Address ConvertFrom(const Address &address)
virtual void DoDispose(void)
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
bool IsExpired(void) const
Definition: event-id.cc:53
a unique identifier for an interface.
Definition: type-id.h:44
TypeId SetParent(TypeId tid)
Definition: type-id.cc:471
void AddHeader(const Header &header)
Definition: packet.cc:270
static TypeId LookupByName(std::string name)
Definition: type-id.cc:415
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.