A Discrete-Event Network Simulator
API
udp-trace-client.cc
Go to the documentation of this file.
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/boolean.h"
32 #include "ns3/string.h"
33 #include "seq-ts-header.h"
34 #include "udp-trace-client.h"
35 #include <cstdlib>
36 #include <cstdio>
37 #include <fstream>
38 
39 namespace ns3 {
40 
41 NS_LOG_COMPONENT_DEFINE ("UdpTraceClient");
42 
43 NS_OBJECT_ENSURE_REGISTERED (UdpTraceClient);
44 
49  { 0, 534, 'I'},
50  { 40, 1542, 'P'},
51  { 120, 134, 'B'},
52  { 80, 390, 'B'},
53  { 240, 765, 'P'},
54  { 160, 407, 'B'},
55  { 200, 504, 'B'},
56  { 360, 903, 'P'},
57  { 280, 421, 'B'},
58  { 320, 587, 'B'}
59 };
60 
61 TypeId
63 {
64  static TypeId tid = TypeId ("ns3::UdpTraceClient")
66  .SetGroupName("Applications")
67  .AddConstructor<UdpTraceClient> ()
68  .AddAttribute ("RemoteAddress",
69  "The destination Address of the outbound packets",
70  AddressValue (),
73  .AddAttribute ("RemotePort",
74  "The destination port of the outbound packets",
75  UintegerValue (100),
77  MakeUintegerChecker<uint16_t> ())
78  .AddAttribute ("MaxPacketSize",
79  "The maximum size of a packet (including the SeqTsHeader, 12 bytes).",
80  UintegerValue (1024),
82  MakeUintegerChecker<uint32_t> ())
83  .AddAttribute ("TraceFilename",
84  "Name of file to load a trace from. By default, uses a hardcoded trace.",
85  StringValue (""),
88  .AddAttribute ("TraceLoop",
89  "Loops through the trace file, starting again once it is over.",
90  BooleanValue (true),
93 
94  ;
95  return tid;
96 }
97 
99 {
100  NS_LOG_FUNCTION (this);
101  m_sent = 0;
102  m_socket = 0;
103  m_sendEvent = EventId ();
104  m_maxPacketSize = 1400;
105 }
106 
108  char *traceFile)
109 {
110  NS_LOG_FUNCTION (this);
111  m_sent = 0;
112  m_socket = 0;
113  m_sendEvent = EventId ();
114  m_peerAddress = ip;
115  m_peerPort = port;
116  m_currentEntry = 0;
117  m_maxPacketSize = 1400;
118  if (traceFile != NULL)
119  {
120  SetTraceFile (traceFile);
121  }
122 }
123 
125 {
126  NS_LOG_FUNCTION (this);
127  m_entries.clear ();
128 }
129 
130 void
132 {
133  NS_LOG_FUNCTION (this << ip << port);
134  m_entries.clear ();
135  m_peerAddress = ip;
136  m_peerPort = port;
137 }
138 
139 void
141 {
142  NS_LOG_FUNCTION (this << addr);
143  m_entries.clear ();
144  m_peerAddress = addr;
145 }
146 
147 void
148 UdpTraceClient::SetTraceFile (std::string traceFile)
149 {
150  NS_LOG_FUNCTION (this << traceFile);
151  if (traceFile == "")
152  {
153  LoadDefaultTrace ();
154  }
155  else
156  {
157  LoadTrace (traceFile);
158  }
159 }
160 
161 void
162 UdpTraceClient::SetMaxPacketSize (uint16_t maxPacketSize)
163 {
164  NS_LOG_FUNCTION (this << maxPacketSize);
165  m_maxPacketSize = maxPacketSize;
166 }
167 
168 
170 {
171  NS_LOG_FUNCTION (this);
172  return m_maxPacketSize;
173 }
174 
175 
176 void
178 {
179  NS_LOG_FUNCTION (this);
181 }
182 
183 void
184 UdpTraceClient::LoadTrace (std::string filename)
185 {
186  NS_LOG_FUNCTION (this << filename);
187  uint32_t time = 0;
188  uint32_t index = 0;
189  uint32_t oldIndex = 0;
190  uint32_t size = 0;
191  uint32_t prevTime = 0;
192  char frameType;
193  TraceEntry entry;
194  std::ifstream ifTraceFile;
195  ifTraceFile.open (filename.c_str (), std::ifstream::in);
196  m_entries.clear ();
197  if (!ifTraceFile.good ())
198  {
199  LoadDefaultTrace ();
200  }
201  while (ifTraceFile.good ())
202  {
203  ifTraceFile >> index >> frameType >> time >> size;
204  if (index == oldIndex)
205  {
206  continue;
207  }
208  if (frameType == 'B')
209  {
210  entry.timeToSend = 0;
211  }
212  else
213  {
214  entry.timeToSend = time - prevTime;
215  prevTime = time;
216  }
217  entry.packetSize = size;
218  entry.frameType = frameType;
219  m_entries.push_back (entry);
220  oldIndex = index;
221  }
222  ifTraceFile.close ();
223  NS_ASSERT_MSG (prevTime != 0, "A trace file can not contain B frames only.");
224  m_currentEntry = 0;
225 }
226 
227 void
229 {
230  NS_LOG_FUNCTION (this);
231  uint32_t prevTime = 0;
232  for (uint32_t i = 0; i < (sizeof (g_defaultEntries) / sizeof (struct TraceEntry)); i++)
233  {
234  struct TraceEntry entry = g_defaultEntries[i];
235  if (entry.frameType == 'B')
236  {
237  entry.timeToSend = 0;
238  }
239  else
240  {
241  uint32_t tmp = entry.timeToSend;
242  entry.timeToSend -= prevTime;
243  prevTime = tmp;
244  }
245  m_entries.push_back (entry);
246  }
247  m_currentEntry = 0;
248 }
249 
250 void
252 {
253  NS_LOG_FUNCTION (this);
254 
255  if (m_socket == 0)
256  {
257  TypeId tid = TypeId::LookupByName ("ns3::UdpSocketFactory");
260  {
261  if (m_socket->Bind () == -1)
262  {
263  NS_FATAL_ERROR ("Failed to bind socket");
264  }
266  }
267  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
268  {
269  if (m_socket->Bind6 () == -1)
270  {
271  NS_FATAL_ERROR ("Failed to bind socket");
272  }
274  }
276  {
277  if (m_socket->Bind () == -1)
278  {
279  NS_FATAL_ERROR ("Failed to bind socket");
280  }
282  }
284  {
285  if (m_socket->Bind6 () == -1)
286  {
287  NS_FATAL_ERROR ("Failed to bind socket");
288  }
290  }
291  else
292  {
293  NS_ASSERT_MSG (false, "Incompatible address type: " << m_peerAddress);
294  }
295  }
297  m_socket->SetAllowBroadcast (true);
299 }
300 
301 void
303 {
304  NS_LOG_FUNCTION (this);
306 }
307 
308 void
310 {
311  NS_LOG_FUNCTION (this << size);
312  Ptr<Packet> p;
313  uint32_t packetSize;
314  if (size>12)
315  {
316  packetSize = size - 12; // 12 is the size of the SeqTsHeader
317  }
318  else
319  {
320  packetSize = 0;
321  }
322  p = Create<Packet> (packetSize);
323  SeqTsHeader seqTs;
324  seqTs.SetSeq (m_sent);
325  p->AddHeader (seqTs);
326 
327  std::stringstream addressString;
329  {
330  addressString << Ipv4Address::ConvertFrom (m_peerAddress);
331  }
332  else if (Ipv6Address::IsMatchingType(m_peerAddress) == true)
333  {
334  addressString << Ipv6Address::ConvertFrom (m_peerAddress);
335  }
336  else
337  {
338  addressString << m_peerAddress;
339  }
340 
341  if ((m_socket->Send (p)) >= 0)
342  {
343  ++m_sent;
344  NS_LOG_INFO ("Sent " << size << " bytes to "
345  << addressString.str ());
346  }
347  else
348  {
349  NS_LOG_INFO ("Error while sending " << size << " bytes to "
350  << addressString.str ());
351  }
352 }
353 
354 void
356 {
357  NS_LOG_FUNCTION (this);
358 
360 
361  bool cycled = false;
362  Ptr<Packet> p;
363  struct TraceEntry *entry = &m_entries[m_currentEntry];
364  do
365  {
366  for (uint32_t i = 0; i < entry->packetSize / m_maxPacketSize; i++)
367  {
369  }
370 
371  uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
372  SendPacket (sizetosend);
373 
374  m_currentEntry++;
375  if (m_currentEntry >= m_entries.size ())
376  {
377  m_currentEntry = 0;
378  cycled = true;
379  }
380  entry = &m_entries[m_currentEntry];
381  }
382  while (entry->timeToSend == 0);
383 
384  if (!cycled || m_traceLoop)
385  {
387  }
388 }
389 
390 void
392 {
393  m_traceLoop = traceLoop;
394 }
395 
396 } // Namespace ns3
a polymophic address class
Definition: address.h:91
AttributeValue implementation for Address.
Definition: address.h:278
The base class for all ns3 applications.
Definition: application.h:61
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
Ptr< Node > GetNode() const
Definition: application.cc:104
AttributeValue implementation for Boolean.
Definition: boolean.h:37
An identifier for simulation events.
Definition: event-id.h:54
bool IsExpired(void) const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:65
An Inet6 address class.
static bool IsMatchingType(const Address &addr)
If the address match.
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv4Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
Packet header to carry sequence number and timestamp.
Definition: seq-ts-header.h:45
void SetSeq(uint32_t seq)
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 &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:556
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
virtual bool SetAllowBroadcast(bool allowBroadcast)=0
Configure whether broadcast datagram transmissions are allowed.
virtual int Bind6()=0
Allocate a local IPv6 endpoint for this socket.
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:71
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Hold variables of type string.
Definition: string.h:41
a unique identifier for an interface.
Definition: type-id.h:59
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition: type-id.cc:829
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Hold an unsigned integer type.
Definition: uinteger.h:44
uint16_t port
Definition: dsdv-manet.cc:45
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:67
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: address.h:278
Ptr< const AttributeChecker > MakeAddressChecker(void)
Definition: address.cc:172
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: boolean.h:85
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: string.h:42
Ptr< const AttributeChecker > MakeStringChecker(void)
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: uinteger.h:45
Callback< R, Ts... > MakeNullCallback(void)
Definition: callback.h:1688
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:281
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1244
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1252
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Entry to send.
uint32_t timeToSend
Time to send the frame.
uint32_t packetSize
Size of the frame.
char frameType
Frame type (I, P or B)
Default trace to send.
EventId m_sendEvent
Event to send the next packet.
void Send(void)
Send a packet.
uint16_t m_peerPort
Remote peer port.
void SetTraceLoop(bool traceLoop)
Set the trace loop flag.
uint32_t m_sent
Counter for sent packets.
void SetRemote(Address ip, uint16_t port)
set the remote address and port
Address m_peerAddress
Remote peer address.
virtual void StopApplication(void)
Application specific shutdown code.
uint32_t m_currentEntry
Current entry index.
void SetTraceFile(std::string filename)
Set the trace file to be used by the application.
void LoadTrace(std::string filename)
Load a trace file.
void SetMaxPacketSize(uint16_t maxPacketSize)
Set the maximum packet size.
std::vector< struct TraceEntry > m_entries
Entries in the trace to send.
virtual void StartApplication(void)
Application specific startup code.
void SendPacket(uint32_t size)
Send a packet of a given size.
uint16_t GetMaxPacketSize(void)
Return the maximum packet size.
bool m_traceLoop
Loop through the trace file.
uint16_t m_maxPacketSize
Maximum packet size to send (including the SeqTsHeader)
virtual void DoDispose(void)
Destructor implementation.
static struct TraceEntry g_defaultEntries[]
Default trace to send.
static TypeId GetTypeId(void)
Get the type ID.
void LoadDefaultTrace(void)
Load the default trace.
Ptr< Socket > m_socket
Socket.
static const uint32_t packetSize