A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Portuguese
Docs ▼
Wiki
Manual
Models
Develop ▼
API
Bugs
API
Main Page
Related Pages
Modules
Namespaces
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Groups
Pages
udp-echo-client.cc
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright 2007 University of Washington
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
#include "ns3/log.h"
19
#include "ns3/ipv4-address.h"
20
#include "ns3/ipv6-address.h"
21
#include "ns3/nstime.h"
22
#include "ns3/inet-socket-address.h"
23
#include "ns3/inet6-socket-address.h"
24
#include "ns3/socket.h"
25
#include "ns3/simulator.h"
26
#include "ns3/socket-factory.h"
27
#include "ns3/packet.h"
28
#include "ns3/uinteger.h"
29
#include "ns3/trace-source-accessor.h"
30
#include "
udp-echo-client.h
"
31
32
namespace
ns3 {
33
34
NS_LOG_COMPONENT_DEFINE
(
"UdpEchoClientApplication"
);
35
NS_OBJECT_ENSURE_REGISTERED
(UdpEchoClient);
36
37
TypeId
38
UdpEchoClient::GetTypeId
(
void
)
39
{
40
static
TypeId
tid =
TypeId
(
"ns3::UdpEchoClient"
)
41
.
SetParent
<
Application
> ()
42
.AddConstructor<UdpEchoClient> ()
43
.AddAttribute (
"MaxPackets"
,
44
"The maximum number of packets the application will send"
,
45
UintegerValue
(100),
46
MakeUintegerAccessor (&
UdpEchoClient::m_count
),
47
MakeUintegerChecker<uint32_t> ())
48
.AddAttribute (
"Interval"
,
49
"The time to wait between packets"
,
50
TimeValue
(
Seconds
(1.0)),
51
MakeTimeAccessor (&
UdpEchoClient::m_interval
),
52
MakeTimeChecker ())
53
.AddAttribute (
"RemoteAddress"
,
54
"The destination Address of the outbound packets"
,
55
AddressValue
(),
56
MakeAddressAccessor (&
UdpEchoClient::m_peerAddress
),
57
MakeAddressChecker ())
58
.AddAttribute (
"RemotePort"
,
59
"The destination port of the outbound packets"
,
60
UintegerValue
(0),
61
MakeUintegerAccessor (&
UdpEchoClient::m_peerPort
),
62
MakeUintegerChecker<uint16_t> ())
63
.AddAttribute (
"PacketSize"
,
"Size of echo data in outbound packets"
,
64
UintegerValue
(100),
65
MakeUintegerAccessor (&
UdpEchoClient::SetDataSize
,
66
&
UdpEchoClient::GetDataSize
),
67
MakeUintegerChecker<uint32_t> ())
68
.AddTraceSource (
"Tx"
,
"A new packet is created and is sent"
,
69
MakeTraceSourceAccessor
(&
UdpEchoClient::m_txTrace
))
70
;
71
return
tid;
72
}
73
74
UdpEchoClient::UdpEchoClient
()
75
{
76
NS_LOG_FUNCTION_NOARGS
();
77
m_sent
= 0;
78
m_socket
= 0;
79
m_sendEvent
=
EventId
();
80
m_data
= 0;
81
m_dataSize
= 0;
82
}
83
84
UdpEchoClient::~UdpEchoClient
()
85
{
86
NS_LOG_FUNCTION_NOARGS
();
87
m_socket
= 0;
88
89
delete
[]
m_data
;
90
m_data
= 0;
91
m_dataSize
= 0;
92
}
93
94
void
95
UdpEchoClient::SetRemote
(
Address
ip, uint16_t
port
)
96
{
97
m_peerAddress
= ip;
98
m_peerPort
=
port
;
99
}
100
101
void
102
UdpEchoClient::SetRemote
(
Ipv4Address
ip, uint16_t
port
)
103
{
104
m_peerAddress
=
Address
(ip);
105
m_peerPort
=
port
;
106
}
107
108
void
109
UdpEchoClient::SetRemote
(
Ipv6Address
ip, uint16_t
port
)
110
{
111
m_peerAddress
=
Address
(ip);
112
m_peerPort
=
port
;
113
}
114
115
void
116
UdpEchoClient::DoDispose
(
void
)
117
{
118
NS_LOG_FUNCTION_NOARGS
();
119
Application::DoDispose
();
120
}
121
122
void
123
UdpEchoClient::StartApplication
(
void
)
124
{
125
NS_LOG_FUNCTION_NOARGS
();
126
127
if
(
m_socket
== 0)
128
{
129
TypeId
tid =
TypeId::LookupByName
(
"ns3::UdpSocketFactory"
);
130
m_socket
=
Socket::CreateSocket
(
GetNode
(), tid);
131
if
(
Ipv4Address::IsMatchingType
(
m_peerAddress
) ==
true
)
132
{
133
m_socket
->
Bind
();
134
m_socket
->
Connect
(
InetSocketAddress
(
Ipv4Address::ConvertFrom
(
m_peerAddress
),
m_peerPort
));
135
}
136
else
if
(
Ipv6Address::IsMatchingType
(
m_peerAddress
) ==
true
)
137
{
138
m_socket
->
Bind6
();
139
m_socket
->
Connect
(
Inet6SocketAddress
(
Ipv6Address::ConvertFrom
(
m_peerAddress
),
m_peerPort
));
140
}
141
}
142
143
m_socket
->
SetRecvCallback
(
MakeCallback
(&
UdpEchoClient::HandleRead
,
this
));
144
145
ScheduleTransmit
(
Seconds
(0.));
146
}
147
148
void
149
UdpEchoClient::StopApplication
()
150
{
151
NS_LOG_FUNCTION_NOARGS
();
152
153
if
(
m_socket
!= 0)
154
{
155
m_socket
->
Close
();
156
m_socket
->
SetRecvCallback
(
MakeNullCallback
<
void
,
Ptr<Socket>
> ());
157
m_socket
= 0;
158
}
159
160
Simulator::Cancel
(
m_sendEvent
);
161
}
162
163
void
164
UdpEchoClient::SetDataSize
(uint32_t dataSize)
165
{
166
NS_LOG_FUNCTION
(dataSize);
167
168
//
169
// If the client is setting the echo packet data size this way, we infer
170
// that she doesn't care about the contents of the packet at all, so
171
// neither will we.
172
//
173
delete
[]
m_data
;
174
m_data
= 0;
175
m_dataSize
= 0;
176
m_size
= dataSize;
177
}
178
179
uint32_t
180
UdpEchoClient::GetDataSize
(
void
)
const
181
{
182
NS_LOG_FUNCTION_NOARGS
();
183
return
m_size
;
184
}
185
186
void
187
UdpEchoClient::SetFill
(std::string fill)
188
{
189
NS_LOG_FUNCTION
(fill);
190
191
uint32_t dataSize = fill.size () + 1;
192
193
if
(dataSize !=
m_dataSize
)
194
{
195
delete
[]
m_data
;
196
m_data
=
new
uint8_t [dataSize];
197
m_dataSize
= dataSize;
198
}
199
200
memcpy (
m_data
, fill.c_str (), dataSize);
201
202
//
203
// Overwrite packet size attribute.
204
//
205
m_size
= dataSize;
206
}
207
208
void
209
UdpEchoClient::SetFill
(uint8_t fill, uint32_t dataSize)
210
{
211
if
(dataSize !=
m_dataSize
)
212
{
213
delete
[]
m_data
;
214
m_data
=
new
uint8_t [dataSize];
215
m_dataSize
= dataSize;
216
}
217
218
memset (
m_data
, fill, dataSize);
219
220
//
221
// Overwrite packet size attribute.
222
//
223
m_size
= dataSize;
224
}
225
226
void
227
UdpEchoClient::SetFill
(uint8_t *fill, uint32_t fillSize, uint32_t dataSize)
228
{
229
if
(dataSize !=
m_dataSize
)
230
{
231
delete
[]
m_data
;
232
m_data
=
new
uint8_t [dataSize];
233
m_dataSize
= dataSize;
234
}
235
236
if
(fillSize >= dataSize)
237
{
238
memcpy (
m_data
, fill, dataSize);
239
m_size
= dataSize;
240
return
;
241
}
242
243
//
244
// Do all but the final fill.
245
//
246
uint32_t filled = 0;
247
while
(filled + fillSize < dataSize)
248
{
249
memcpy (&
m_data
[filled], fill, fillSize);
250
filled += fillSize;
251
}
252
253
//
254
// Last fill may be partial
255
//
256
memcpy (&
m_data
[filled], fill, dataSize - filled);
257
258
//
259
// Overwrite packet size attribute.
260
//
261
m_size
= dataSize;
262
}
263
264
void
265
UdpEchoClient::ScheduleTransmit
(
Time
dt)
266
{
267
NS_LOG_FUNCTION_NOARGS
();
268
m_sendEvent
=
Simulator::Schedule
(dt, &
UdpEchoClient::Send
,
this
);
269
}
270
271
void
272
UdpEchoClient::Send
(
void
)
273
{
274
NS_LOG_FUNCTION_NOARGS
();
275
276
NS_ASSERT
(
m_sendEvent
.
IsExpired
());
277
278
Ptr<Packet>
p;
279
if
(
m_dataSize
)
280
{
281
//
282
// If m_dataSize is non-zero, we have a data buffer of the same size that we
283
// are expected to copy and send. This state of affairs is created if one of
284
// the Fill functions is called. In this case, m_size must have been set
285
// to agree with m_dataSize
286
//
287
NS_ASSERT_MSG
(
m_dataSize
==
m_size
,
"UdpEchoClient::Send(): m_size and m_dataSize inconsistent"
);
288
NS_ASSERT_MSG
(
m_data
,
"UdpEchoClient::Send(): m_dataSize but no m_data"
);
289
p = Create<Packet> (
m_data
,
m_dataSize
);
290
}
291
else
292
{
293
//
294
// If m_dataSize is zero, the client has indicated that she doesn't care
295
// about the data itself either by specifying the data size by setting
296
// the corresponding atribute or by not calling a SetFill function. In
297
// this case, we don't worry about it either. But we do allow m_size
298
// to have a value different from the (zero) m_dataSize.
299
//
300
p = Create<Packet> (
m_size
);
301
}
302
// call to the trace sinks before the packet is actually sent,
303
// so that tags added to the packet can be sent as well
304
m_txTrace
(p);
305
m_socket
->
Send
(p);
306
307
++
m_sent
;
308
309
if
(
Ipv4Address::IsMatchingType
(
m_peerAddress
))
310
{
311
NS_LOG_INFO
(
"At time "
<<
Simulator::Now
().GetSeconds () <<
"s client sent "
<<
m_size
<<
" bytes to "
<<
312
Ipv4Address::ConvertFrom
(
m_peerAddress
) <<
" port "
<<
m_peerPort
);
313
}
314
else
if
(
Ipv6Address::IsMatchingType
(
m_peerAddress
))
315
{
316
NS_LOG_INFO
(
"At time "
<<
Simulator::Now
().GetSeconds () <<
"s client sent "
<<
m_size
<<
" bytes to "
<<
317
Ipv6Address::ConvertFrom
(
m_peerAddress
) <<
" port "
<<
m_peerPort
);
318
}
319
320
if
(
m_sent
<
m_count
)
321
{
322
ScheduleTransmit
(
m_interval
);
323
}
324
}
325
326
void
327
UdpEchoClient::HandleRead
(
Ptr<Socket>
socket)
328
{
329
NS_LOG_FUNCTION
(
this
<< socket);
330
Ptr<Packet>
packet;
331
Address
from;
332
while
((packet = socket->
RecvFrom
(from)))
333
{
334
if
(
InetSocketAddress::IsMatchingType
(from))
335
{
336
NS_LOG_INFO
(
"At time "
<<
Simulator::Now
().GetSeconds () <<
"s client received "
<< packet->
GetSize
() <<
" bytes from "
<<
337
InetSocketAddress::ConvertFrom
(from).
GetIpv4
() <<
" port "
<<
338
InetSocketAddress::ConvertFrom
(from).
GetPort
());
339
}
340
else
if
(
Inet6SocketAddress::IsMatchingType
(from))
341
{
342
NS_LOG_INFO
(
"At time "
<<
Simulator::Now
().GetSeconds () <<
"s client received "
<< packet->
GetSize
() <<
" bytes from "
<<
343
Inet6SocketAddress::ConvertFrom
(from).
GetIpv6
() <<
" port "
<<
344
Inet6SocketAddress::ConvertFrom
(from).
GetPort
());
345
}
346
}
347
}
348
349
}
// Namespace ns3
src
applications
model
udp-echo-client.cc
Generated on Tue Oct 9 2012 16:45:33 for ns-3 by
1.8.1.2