A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
udp-trace-client.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007,2008, 2009 INRIA, UDcast
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
7 * <amine.ismail@udcast.com>
8 */
9#include "udp-trace-client.h"
10
11#include "seq-ts-header.h"
12
13#include "ns3/address-utils.h"
14#include "ns3/boolean.h"
15#include "ns3/log.h"
16#include "ns3/nstime.h"
17#include "ns3/packet.h"
18#include "ns3/simulator.h"
19#include "ns3/socket-factory.h"
20#include "ns3/socket.h"
21#include "ns3/string.h"
22#include "ns3/uinteger.h"
23
24#include <cstdio>
25#include <cstdlib>
26#include <fstream>
27
28namespace ns3
29{
30
31NS_LOG_COMPONENT_DEFINE("UdpTraceClient");
32
33NS_OBJECT_ENSURE_REGISTERED(UdpTraceClient);
34
35/**
36 * @brief Default trace to send
37 */
38UdpTraceClient::TraceEntry UdpTraceClient::g_defaultEntries[] = {
39 {0, 534, 'I'},
40 {40, 1542, 'P'},
41 {120, 134, 'B'},
42 {80, 390, 'B'},
43 {240, 765, 'P'},
44 {160, 407, 'B'},
45 {200, 504, 'B'},
46 {360, 903, 'P'},
47 {280, 421, 'B'},
48 {320, 587, 'B'},
49};
50
51TypeId
53{
54 static TypeId tid =
55 TypeId("ns3::UdpTraceClient")
57 .SetGroupName("Applications")
58 .AddConstructor<UdpTraceClient>()
59 // NS_DEPRECATED_3_44
60 .AddAttribute(
61 "RemoteAddress",
62 "The destination Address of the outbound packets",
65 // this is needed to indicate which version of the function overload to use
66 static_cast<void (UdpTraceClient::*)(const Address&)>(
70 "Replaced by Remote in ns-3.44.")
71 // NS_DEPRECATED_3_44
72 .AddAttribute(
73 "RemotePort",
74 "The destination port of the outbound packets",
77 // this is needed to indicate which version of the function overload to use
78 static_cast<void (UdpTraceClient::*)(const Address&)>(
83 "Replaced by Remote in ns-3.44.")
84 .AddAttribute("MaxPacketSize",
85 "The maximum size of a packet (including the SeqTsHeader, 12 bytes).",
86 UintegerValue(1024),
89 .AddAttribute("TraceFilename",
90 "Name of file to load a trace from. By default, uses a hardcoded trace.",
91 StringValue(""),
94 .AddAttribute("TraceLoop",
95 "Loops through the trace file, starting again once it is over.",
96 BooleanValue(true),
99
100 ;
101 return tid;
102}
103
105 : m_sent{0},
106 m_socket{nullptr},
107 m_peerPort{},
108 m_sendEvent{},
109 m_currentEntry{0}
110{
111 NS_LOG_FUNCTION(this);
112}
113
118
119void
121{
122 NS_LOG_FUNCTION(this << ip << port);
123 SetRemote(ip);
124 SetPort(port);
125}
126
127void
129{
130 NS_LOG_FUNCTION(this << addr);
131 if (!addr.IsInvalid())
132 {
133 m_peer = addr;
134 if (m_peerPort)
135 {
137 }
138 LoadTrace();
139 }
140}
141
144{
145 return m_peer;
146}
147
148void
150{
151 NS_LOG_FUNCTION(this << port);
152 if (m_peer.IsInvalid())
153 {
154 // save for later
156 return;
157 }
159 {
161 }
162}
163
164uint16_t
181
182void
183UdpTraceClient::SetTraceFile(const std::string& traceFile)
184{
185 NS_LOG_FUNCTION(this << traceFile);
186 m_traceFile = traceFile;
187 LoadTrace();
188}
189
190void
191UdpTraceClient::SetMaxPacketSize(uint16_t maxPacketSize)
192{
193 NS_LOG_FUNCTION(this << maxPacketSize);
194 m_maxPacketSize = maxPacketSize;
195}
196
197uint16_t
203
204void
206{
207 NS_LOG_FUNCTION(this);
208 m_entries.clear();
209 m_currentEntry = 0;
210
211 if (m_traceFile.empty())
212 {
214 return;
215 }
216
217 std::ifstream ifTraceFile;
218 ifTraceFile.open(m_traceFile, std::ifstream::in);
219 if (!ifTraceFile.good())
220 {
222 return;
223 }
224
225 uint32_t oldIndex = 0;
226 uint32_t prevTime = 0;
227 while (ifTraceFile.good())
228 {
229 uint32_t index = 0;
230 char frameType;
231 uint32_t time = 0;
232 uint32_t size = 0;
233 ifTraceFile >> index >> frameType >> time >> size;
234
235 if (index == oldIndex)
236 {
237 continue;
238 }
239
240 TraceEntry entry{};
241 if (frameType == 'B')
242 {
243 entry.timeToSend = 0;
244 }
245 else
246 {
247 entry.timeToSend = time - prevTime;
248 prevTime = time;
249 }
250 entry.packetSize = size;
251 entry.frameType = frameType;
252 m_entries.push_back(entry);
253 oldIndex = index;
254 }
255
256 ifTraceFile.close();
257 NS_ASSERT_MSG(prevTime != 0, "A trace file can not contain B frames only.");
258}
259
260void
262{
263 NS_LOG_FUNCTION(this);
264 uint32_t prevTime = 0;
265 for (uint32_t i = 0; i < (sizeof(g_defaultEntries) / sizeof(TraceEntry)); i++)
266 {
267 TraceEntry entry = g_defaultEntries[i];
268 if (entry.frameType == 'B')
269 {
270 entry.timeToSend = 0;
271 }
272 else
273 {
274 uint32_t tmp = entry.timeToSend;
275 entry.timeToSend -= prevTime;
276 prevTime = tmp;
277 }
278 m_entries.push_back(entry);
279 }
280}
281
282void
284{
285 NS_LOG_FUNCTION(this);
286
287 if (!m_socket)
288 {
289 auto tid = TypeId::LookupByName("ns3::UdpSocketFactory");
291 NS_ABORT_MSG_IF(m_peer.IsInvalid(), "Remote address not properly set");
292 if (!m_local.IsInvalid())
293 {
298 "Incompatible peer and local address IP version");
299 if (m_socket->Bind(m_local) == -1)
300 {
301 NS_FATAL_ERROR("Failed to bind socket");
302 }
303 }
304 else
305 {
307 {
308 if (m_socket->Bind() == -1)
309 {
310 NS_FATAL_ERROR("Failed to bind socket");
311 }
312 }
314 {
315 if (m_socket->Bind6() == -1)
316 {
317 NS_FATAL_ERROR("Failed to bind socket");
318 }
319 }
320 else
321 {
322 NS_ASSERT_MSG(false, "Incompatible address type: " << m_peer);
323 }
324 }
325 m_socket->SetIpTos(m_tos); // Affects only IPv4 sockets.
329 }
331}
332
333void
339
340void
342{
343 NS_LOG_FUNCTION(this << size);
345 if (size > 12)
346 {
347 packetSize = size - 12; // 12 is the size of the SeqTsHeader
348 }
349 else
350 {
351 packetSize = 0;
352 }
353 auto p = Create<Packet>(packetSize);
354 SeqTsHeader seqTs;
355 seqTs.SetSeq(m_sent);
356 p->AddHeader(seqTs);
357
358 std::stringstream addressString{};
359#ifdef NS3_LOG_ENABLE
361 {
362 addressString << InetSocketAddress::ConvertFrom(m_peer).GetIpv4() << ":"
364 }
366 {
367 addressString << Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6() << ":"
369 }
370#endif
371
372 if ((m_socket->Send(p)) >= 0)
373 {
374 ++m_sent;
375 NS_LOG_INFO("Sent " << size << " bytes to " << addressString.str());
376 }
377 else
378 {
379 NS_LOG_INFO("Error while sending " << size << " bytes to " << addressString.str());
380 }
381}
382
383void
385{
386 NS_LOG_FUNCTION(this);
387
389
390 bool cycled = false;
391 Ptr<Packet> p;
393 do
394 {
395 for (uint32_t i = 0; i < entry->packetSize / m_maxPacketSize; i++)
396 {
398 }
399
400 auto sizetosend = entry->packetSize % m_maxPacketSize;
401 SendPacket(sizetosend);
402
404 if (m_currentEntry >= m_entries.size())
405 {
406 m_currentEntry = 0;
407 cycled = true;
408 }
409 entry = &m_entries[m_currentEntry];
410 } while (entry->timeToSend == 0);
411
412 if (!cycled || m_traceLoop)
413 {
416 }
417}
418
419void
421{
422 m_traceLoop = traceLoop;
423}
424
425} // Namespace ns3
a polymophic address class
Definition address.h:90
bool IsInvalid() const
Definition address.cc:60
AttributeValue implementation for Address.
Definition address.h:275
Ptr< Node > GetNode() const
AttributeValue implementation for Boolean.
Definition boolean.h:26
bool IsExpired() const
This method is syntactic sugar for the ns3::Simulator::IsExpired method.
Definition event-id.cc:58
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t GetPort() const
Get the port.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
static bool IsMatchingType(const Address &address)
static bool IsMatchingType(const Address &address)
If the Address matches the type.
Smart pointer class similar to boost::intrusive_ptr.
Packet header to carry sequence number and timestamp.
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:561
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:274
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:595
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
void SetIpTos(uint8_t ipTos)
Manually set IP Type of Service field.
Definition socket.cc:423
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:117
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:61
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
Base class for source applications.
Address m_local
Local address to bind to.
uint8_t m_tos
The packets Type of Service.
Address m_peer
Peer address.
Hold variables of type string.
Definition string.h:45
a unique identifier for an interface.
Definition type-id.h:49
static TypeId LookupByName(std::string name)
Get a TypeId by name.
Definition type-id.cc:872
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
@ DEPRECATED
Attribute or trace source is deprecated; user is warned.
A trace based streamer.
EventId m_sendEvent
Event to send the next packet.
void SetTraceFile(const std::string &filename)
Set the trace file to be used by the application.
void StopApplication() override
Application specific shutdown code.
Address GetRemote() const
Get the remote address (temporary function until deprecated attributes are removed)
static TypeId GetTypeId()
Get the type ID.
void Send()
Send a packet.
std::optional< uint16_t > m_peerPort
Remote peer port (deprecated) // NS_DEPRECATED_3_44.
void SetTraceLoop(bool traceLoop)
Set the trace loop flag.
uint32_t m_sent
Counter for sent packets.
std::vector< TraceEntry > m_entries
Entries in the trace to send.
uint32_t m_currentEntry
Current entry index.
void SetMaxPacketSize(uint16_t maxPacketSize)
Set the maximum packet size.
void LoadTrace()
Load current trace file.
void SetPort(uint16_t port)
Set the remote port (temporary function until deprecated attributes are removed)
void StartApplication() override
Application specific startup code.
static constexpr uint16_t DEFAULT_PORT
default port
void SetRemote(const Address &ip, uint16_t port)
set the remote address and port
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)
std::string m_traceFile
The location of the trace file.
static TraceEntry g_defaultEntries[]
Default trace to send.
uint16_t GetPort() const
Get the remote port (temporary function until deprecated attributes are removed)
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:34
uint16_t port
Definition dsdv-manet.cc:33
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#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:75
Ptr< const AttributeChecker > MakeAddressChecker()
Definition address.cc:169
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:275
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:113
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:70
Ptr< const AttributeChecker > MakeStringChecker()
Definition string.cc:19
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:46
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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:35
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#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:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1357
Address ConvertToSocketAddress(const Address &address, uint16_t port)
Convert IPv4/IPv6 address with port to a socket address.
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)
Time prevTime
static const uint32_t packetSize
Packet size generated at the AP.