A Discrete-Event Network Simulator
API
udp-trace-client.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
18  * <amine.ismail@udcast.com>
19  */
20 #include "udp-trace-client.h"
21 
22 #include "seq-ts-header.h"
23 
24 #include "ns3/boolean.h"
25 #include "ns3/inet-socket-address.h"
26 #include "ns3/inet6-socket-address.h"
27 #include "ns3/ipv4-address.h"
28 #include "ns3/log.h"
29 #include "ns3/nstime.h"
30 #include "ns3/packet.h"
31 #include "ns3/simulator.h"
32 #include "ns3/socket-factory.h"
33 #include "ns3/socket.h"
34 #include "ns3/string.h"
35 #include "ns3/uinteger.h"
36 
37 #include <cstdio>
38 #include <cstdlib>
39 #include <fstream>
40 
41 namespace ns3
42 {
43 
44 NS_LOG_COMPONENT_DEFINE("UdpTraceClient");
45 
46 NS_OBJECT_ENSURE_REGISTERED(UdpTraceClient);
47 
51 UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
52  {0, 534, 'I'},
53  {40, 1542, 'P'},
54  {120, 134, 'B'},
55  {80, 390, 'B'},
56  {240, 765, 'P'},
57  {160, 407, 'B'},
58  {200, 504, 'B'},
59  {360, 903, 'P'},
60  {280, 421, 'B'},
61  {320, 587, 'B'},
62 };
63 
64 TypeId
66 {
67  static TypeId tid =
68  TypeId("ns3::UdpTraceClient")
70  .SetGroupName("Applications")
71  .AddConstructor<UdpTraceClient>()
72  .AddAttribute("RemoteAddress",
73  "The destination Address of the outbound packets",
74  AddressValue(),
75  MakeAddressAccessor(&UdpTraceClient::m_peerAddress),
76  MakeAddressChecker())
77  .AddAttribute("RemotePort",
78  "The destination port of the outbound packets",
79  UintegerValue(100),
81  MakeUintegerChecker<uint16_t>())
82  .AddAttribute("MaxPacketSize",
83  "The maximum size of a packet (including the SeqTsHeader, 12 bytes).",
84  UintegerValue(1024),
86  MakeUintegerChecker<uint32_t>())
87  .AddAttribute("TraceFilename",
88  "Name of file to load a trace from. By default, uses a hardcoded trace.",
89  StringValue(""),
92  .AddAttribute("TraceLoop",
93  "Loops through the trace file, starting again once it is over.",
94  BooleanValue(true),
97 
98  ;
99  return tid;
100 }
101 
103 {
104  NS_LOG_FUNCTION(this);
105  m_sent = 0;
106  m_socket = nullptr;
107  m_sendEvent = EventId();
108  m_maxPacketSize = 1400;
109 }
110 
111 UdpTraceClient::UdpTraceClient(Ipv4Address ip, uint16_t port, char* traceFile)
112 {
113  NS_LOG_FUNCTION(this);
114  m_sent = 0;
115  m_socket = nullptr;
116  m_sendEvent = EventId();
117  m_peerAddress = ip;
118  m_peerPort = port;
119  m_currentEntry = 0;
120  m_maxPacketSize = 1400;
121  if (traceFile != nullptr)
122  {
123  SetTraceFile(traceFile);
124  }
125 }
126 
128 {
129  NS_LOG_FUNCTION(this);
130  m_entries.clear();
131 }
132 
133 void
135 {
136  NS_LOG_FUNCTION(this << ip << port);
137  m_entries.clear();
138  m_peerAddress = ip;
139  m_peerPort = port;
140 }
141 
142 void
144 {
145  NS_LOG_FUNCTION(this << addr);
146  m_entries.clear();
147  m_peerAddress = addr;
148 }
149 
150 void
151 UdpTraceClient::SetTraceFile(std::string traceFile)
152 {
153  NS_LOG_FUNCTION(this << traceFile);
154  if (traceFile.empty())
155  {
157  }
158  else
159  {
160  LoadTrace(traceFile);
161  }
162 }
163 
164 void
165 UdpTraceClient::SetMaxPacketSize(uint16_t maxPacketSize)
166 {
167  NS_LOG_FUNCTION(this << maxPacketSize);
168  m_maxPacketSize = maxPacketSize;
169 }
170 
171 uint16_t
173 {
174  NS_LOG_FUNCTION(this);
175  return m_maxPacketSize;
176 }
177 
178 void
180 {
181  NS_LOG_FUNCTION(this);
183 }
184 
185 void
186 UdpTraceClient::LoadTrace(std::string filename)
187 {
188  NS_LOG_FUNCTION(this << filename);
189  uint32_t time = 0;
190  uint32_t index = 0;
191  uint32_t oldIndex = 0;
192  uint32_t size = 0;
193  uint32_t prevTime = 0;
194  char frameType;
195  TraceEntry entry;
196  std::ifstream ifTraceFile;
197  ifTraceFile.open(filename, std::ifstream::in);
198  m_entries.clear();
199  if (!ifTraceFile.good())
200  {
202  }
203  while (ifTraceFile.good())
204  {
205  ifTraceFile >> index >> frameType >> time >> size;
206  if (index == oldIndex)
207  {
208  continue;
209  }
210  if (frameType == 'B')
211  {
212  entry.timeToSend = 0;
213  }
214  else
215  {
216  entry.timeToSend = time - prevTime;
217  prevTime = time;
218  }
219  entry.packetSize = size;
220  entry.frameType = frameType;
221  m_entries.push_back(entry);
222  oldIndex = index;
223  }
224  ifTraceFile.close();
225  NS_ASSERT_MSG(prevTime != 0, "A trace file can not contain B frames only.");
226  m_currentEntry = 0;
227 }
228 
229 void
231 {
232  NS_LOG_FUNCTION(this);
233  uint32_t prevTime = 0;
234  for (uint32_t i = 0; i < (sizeof(g_defaultEntries) / sizeof(TraceEntry)); i++)
235  {
236  TraceEntry entry = g_defaultEntries[i];
237  if (entry.frameType == 'B')
238  {
239  entry.timeToSend = 0;
240  }
241  else
242  {
243  uint32_t tmp = entry.timeToSend;
244  entry.timeToSend -= prevTime;
245  prevTime = tmp;
246  }
247  m_entries.push_back(entry);
248  }
249  m_currentEntry = 0;
250 }
251 
252 void
254 {
255  NS_LOG_FUNCTION(this);
256 
257  if (!m_socket)
258  {
259  TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
262  {
263  if (m_socket->Bind() == -1)
264  {
265  NS_FATAL_ERROR("Failed to bind socket");
266  }
267  m_socket->Connect(
269  }
271  {
272  if (m_socket->Bind6() == -1)
273  {
274  NS_FATAL_ERROR("Failed to bind socket");
275  }
276  m_socket->Connect(
278  }
280  {
281  if (m_socket->Bind() == -1)
282  {
283  NS_FATAL_ERROR("Failed to bind socket");
284  }
286  }
288  {
289  if (m_socket->Bind6() == -1)
290  {
291  NS_FATAL_ERROR("Failed to bind socket");
292  }
294  }
295  else
296  {
297  NS_ASSERT_MSG(false, "Incompatible address type: " << m_peerAddress);
298  }
299  }
303 }
304 
305 void
307 {
308  NS_LOG_FUNCTION(this);
310 }
311 
312 void
314 {
315  NS_LOG_FUNCTION(this << size);
316  Ptr<Packet> p;
317  uint32_t packetSize;
318  if (size > 12)
319  {
320  packetSize = size - 12; // 12 is the size of the SeqTsHeader
321  }
322  else
323  {
324  packetSize = 0;
325  }
326  p = Create<Packet>(packetSize);
327  SeqTsHeader seqTs;
328  seqTs.SetSeq(m_sent);
329  p->AddHeader(seqTs);
330 
331  std::stringstream addressString;
333  {
334  addressString << Ipv4Address::ConvertFrom(m_peerAddress);
335  }
337  {
338  addressString << Ipv6Address::ConvertFrom(m_peerAddress);
339  }
340  else
341  {
342  addressString << m_peerAddress;
343  }
344 
345  if ((m_socket->Send(p)) >= 0)
346  {
347  ++m_sent;
348  NS_LOG_INFO("Sent " << size << " bytes to " << addressString.str());
349  }
350  else
351  {
352  NS_LOG_INFO("Error while sending " << size << " bytes to " << addressString.str());
353  }
354 }
355 
356 void
358 {
359  NS_LOG_FUNCTION(this);
360 
362 
363  bool cycled = false;
364  Ptr<Packet> p;
366  do
367  {
368  for (uint32_t i = 0; i < entry->packetSize / m_maxPacketSize; i++)
369  {
371  }
372 
373  uint16_t sizetosend = entry->packetSize % m_maxPacketSize;
374  SendPacket(sizetosend);
375 
376  m_currentEntry++;
377  if (m_currentEntry >= m_entries.size())
378  {
379  m_currentEntry = 0;
380  cycled = true;
381  }
382  entry = &m_entries[m_currentEntry];
383  } while (entry->timeToSend == 0);
384 
385  if (!cycled || m_traceLoop)
386  {
387  m_sendEvent =
389  }
390 }
391 
392 void
394 {
395  m_traceLoop = traceLoop;
396 }
397 
398 } // Namespace ns3
a polymophic address class
Definition: address.h:101
The base class for all ns3 applications.
Definition: application.h:62
void DoDispose() override
Destructor implementation.
Definition: application.cc:86
Ptr< Node > GetNode() const
Definition: application.cc:108
An identifier for simulation events.
Definition: event-id.h:55
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition: event-id.cc:69
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:42
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:268
Packet header to carry sequence number and timestamp.
Definition: seq-ts-header.h:45
void SetSeq(uint32_t seq)
static EventId Schedule(const Time &delay, FUNC f, Ts &&... args)
Schedule an event to expire after delay.
Definition: simulator.h:571
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:285
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.
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
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.
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:72
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Hold variables of type string.
Definition: string.h:56
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:835
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
A trace based streamer.
EventId m_sendEvent
Event to send the next packet.
void StopApplication() override
Application specific shutdown code.
static TypeId GetTypeId()
Get the type ID.
void Send()
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.
std::vector< TraceEntry > m_entries
Entries in the trace to send.
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.
void StartApplication() override
Application specific startup code.
void DoDispose() override
Destructor implementation.
void SendPacket(uint32_t size)
Send a packet of a given size.
bool m_traceLoop
Loop through the trace file.
uint16_t m_maxPacketSize
Maximum packet size to send (including the SeqTsHeader)
static TraceEntry g_defaultEntries[]
Default trace to send.
uint16_t GetMaxPacketSize()
Return the maximum packet size.
void LoadDefaultTrace()
Load the default trace.
Ptr< Socket > m_socket
Socket.
Hold an unsigned integer type.
Definition: uinteger.h:45
uint16_t port
Definition: dsdv-manet.cc:44
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#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:86
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:1326
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition: nstime.h:1338
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
Ptr< const AttributeChecker > MakeStringChecker()
Definition: string.cc:30
Ptr< const AttributeAccessor > MakeStringAccessor(T1 a1)
Definition: string.h:57
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)
Time prevTime
static const uint32_t packetSize
Packet size generated at the AP.