A Discrete-Event Network Simulator
API
bulk-send-application.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Georgia Institute of Technology
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: George F. Riley <riley@ece.gatech.edu>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/address.h"
23 #include "ns3/node.h"
24 #include "ns3/nstime.h"
25 #include "ns3/socket.h"
26 #include "ns3/simulator.h"
27 #include "ns3/socket-factory.h"
28 #include "ns3/packet.h"
29 #include "ns3/uinteger.h"
30 #include "ns3/trace-source-accessor.h"
31 #include "ns3/tcp-socket-factory.h"
32 #include "ns3/boolean.h"
33 #include "bulk-send-application.h"
34 
35 namespace ns3 {
36 
37 NS_LOG_COMPONENT_DEFINE ("BulkSendApplication");
38 
39 NS_OBJECT_ENSURE_REGISTERED (BulkSendApplication);
40 
41 TypeId
43 {
44  static TypeId tid = TypeId ("ns3::BulkSendApplication")
46  .SetGroupName("Applications")
47  .AddConstructor<BulkSendApplication> ()
48  .AddAttribute ("SendSize", "The amount of data to send each time.",
49  UintegerValue (512),
51  MakeUintegerChecker<uint32_t> (1))
52  .AddAttribute ("Remote", "The address of the destination",
53  AddressValue (),
56  .AddAttribute ("Local",
57  "The Address on which to bind the socket. If not set, it is generated automatically.",
58  AddressValue (),
61  .AddAttribute ("MaxBytes",
62  "The total number of bytes to send. "
63  "Once these bytes are sent, "
64  "no data is sent again. The value zero means "
65  "that there is no limit.",
66  UintegerValue (0),
68  MakeUintegerChecker<uint64_t> ())
69  .AddAttribute ("Protocol", "The type of protocol to use.",
73  .AddAttribute ("EnableSeqTsSizeHeader",
74  "Add SeqTsSizeHeader to each packet",
75  BooleanValue (false),
78  .AddTraceSource ("Tx", "A new packet is sent",
80  "ns3::Packet::TracedCallback")
81  .AddTraceSource ("TxWithSeqTsSize", "A new packet is created with SeqTsSizeHeader",
83  "ns3::PacketSink::SeqTsSizeCallback")
84  ;
85  return tid;
86 }
87 
88 
90  : m_socket (0),
91  m_connected (false),
92  m_totBytes (0),
93  m_unsentPacket (0)
94 {
95  NS_LOG_FUNCTION (this);
96 }
97 
99 {
100  NS_LOG_FUNCTION (this);
101 }
102 
103 void
105 {
106  NS_LOG_FUNCTION (this << maxBytes);
107  m_maxBytes = maxBytes;
108 }
109 
112 {
113  NS_LOG_FUNCTION (this);
114  return m_socket;
115 }
116 
117 void
119 {
120  NS_LOG_FUNCTION (this);
121 
122  m_socket = 0;
123  m_unsentPacket = 0;
124  // chain up
126 }
127 
128 // Application Methods
129 void BulkSendApplication::StartApplication (void) // Called at time specified by Start
130 {
131  NS_LOG_FUNCTION (this);
132  Address from;
133 
134  // Create the socket if not already
135  if (!m_socket)
136  {
138  int ret = -1;
139 
140  // Fatal error if socket type is not NS3_SOCK_STREAM or NS3_SOCK_SEQPACKET
143  {
144  NS_FATAL_ERROR ("Using BulkSend with an incompatible socket type. "
145  "BulkSend requires SOCK_STREAM or SOCK_SEQPACKET. "
146  "In other words, use TCP instead of UDP.");
147  }
148 
149  if (! m_local.IsInvalid())
150  {
153  "Incompatible peer and local address IP version");
154  ret = m_socket->Bind (m_local);
155  }
156  else
157  {
159  {
160  ret = m_socket->Bind6 ();
161  }
163  {
164  ret = m_socket->Bind ();
165  }
166  }
167 
168  if (ret == -1)
169  {
170  NS_FATAL_ERROR ("Failed to bind socket");
171  }
172 
180  }
181  if (m_connected)
182  {
183  m_socket->GetSockName (from);
184  SendData (from, m_peer);
185  }
186 }
187 
188 void BulkSendApplication::StopApplication (void) // Called at time specified by Stop
189 {
190  NS_LOG_FUNCTION (this);
191 
192  if (m_socket != 0)
193  {
194  m_socket->Close ();
195  m_connected = false;
196  }
197  else
198  {
199  NS_LOG_WARN ("BulkSendApplication found null socket to close in StopApplication");
200  }
201 }
202 
203 
204 // Private helpers
205 
206 void BulkSendApplication::SendData (const Address &from, const Address &to)
207 {
208  NS_LOG_FUNCTION (this);
209 
210  while (m_maxBytes == 0 || m_totBytes < m_maxBytes)
211  { // Time to send more
212 
213  // uint64_t to allow the comparison later.
214  // the result is in a uint32_t range anyway, because
215  // m_sendSize is uint32_t.
216  uint64_t toSend = m_sendSize;
217  // Make sure we don't send too many
218  if (m_maxBytes > 0)
219  {
220  toSend = std::min (toSend, m_maxBytes - m_totBytes);
221  }
222 
223  NS_LOG_LOGIC ("sending packet at " << Simulator::Now ());
224 
225  Ptr<Packet> packet;
226  if (m_unsentPacket)
227  {
228  packet = m_unsentPacket;
229  toSend = packet->GetSize ();
230  }
231  else if (m_enableSeqTsSizeHeader)
232  {
233  SeqTsSizeHeader header;
234  header.SetSeq (m_seq++);
235  header.SetSize (toSend);
236  NS_ABORT_IF (toSend < header.GetSerializedSize ());
237  packet = Create<Packet> (toSend - header.GetSerializedSize ());
238  // Trace before adding header, for consistency with PacketSink
239  m_txTraceWithSeqTsSize (packet, from, to, header);
240  packet->AddHeader (header);
241  }
242  else
243  {
244  packet = Create<Packet> (toSend);
245  }
246 
247  int actual = m_socket->Send (packet);
248  if ((unsigned) actual == toSend)
249  {
250  m_totBytes += actual;
251  m_txTrace (packet);
252  m_unsentPacket = 0;
253  }
254  else if (actual == -1)
255  {
256  // We exit this loop when actual < toSend as the send side
257  // buffer is full. The "DataSent" callback will pop when
258  // some buffer space has freed up.
259  NS_LOG_DEBUG ("Unable to send packet; caching for later attempt");
260  m_unsentPacket = packet;
261  break;
262  }
263  else if (actual > 0 && (unsigned) actual < toSend)
264  {
265  // A Linux socket (non-blocking, such as in DCE) may return
266  // a quantity less than the packet size. Split the packet
267  // into two, trace the sent packet, save the unsent packet
268  NS_LOG_DEBUG ("Packet size: " << packet->GetSize () << "; sent: " << actual << "; fragment saved: " << toSend - (unsigned) actual);
269  Ptr<Packet> sent = packet->CreateFragment (0, actual);
270  Ptr<Packet> unsent = packet->CreateFragment (actual, (toSend - (unsigned) actual));
271  m_totBytes += actual;
272  m_txTrace (sent);
273  m_unsentPacket = unsent;
274  break;
275  }
276  else
277  {
278  NS_FATAL_ERROR ("Unexpected return value from m_socket->Send ()");
279  }
280  }
281  // Check if time to close (all sent)
283  {
284  m_socket->Close ();
285  m_connected = false;
286  }
287 }
288 
290 {
291  NS_LOG_FUNCTION (this << socket);
292  NS_LOG_LOGIC ("BulkSendApplication Connection succeeded");
293  m_connected = true;
294  Address from, to;
295  socket->GetSockName (from);
296  socket->GetPeerName (to);
297  SendData (from, to);
298 }
299 
301 {
302  NS_LOG_FUNCTION (this << socket);
303  NS_LOG_LOGIC ("BulkSendApplication, Connection Failed");
304 }
305 
307 {
308  NS_LOG_FUNCTION (this);
309 
310  if (m_connected)
311  { // Only send new data if the connection has completed
312  Address from, to;
313  socket->GetSockName (from);
314  socket->GetPeerName (to);
315  SendData (from, to);
316  }
317 }
318 
319 
320 
321 } // Namespace ns3
ns3::TypeId
a unique identifier for an interface.
Definition: type-id.h:59
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
ns3::SeqTsSizeHeader::GetSerializedSize
virtual uint32_t GetSerializedSize(void) const override
Definition: seq-ts-size-header.cc:75
ns3::Inet6SocketAddress::IsMatchingType
static bool IsMatchingType(const Address &addr)
If the address match.
Definition: inet6-socket-address.cc:89
NS_OBJECT_ENSURE_REGISTERED
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:45
ns3::SeqTsSizeHeader
Header with a sequence, a timestamp, and a "size" attribute.
Definition: seq-ts-size-header.h:38
ns3::InetSocketAddress::IsMatchingType
static bool IsMatchingType(const Address &address)
Definition: inet-socket-address.cc:103
ns3::BooleanValue
AttributeValue implementation for Boolean.
Definition: boolean.h:37
ns3::BulkSendApplication::ConnectionFailed
void ConnectionFailed(Ptr< Socket > socket)
Connection Failed (called by Socket through a callback)
Definition: bulk-send-application.cc:300
ns3::Socket::Bind
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
ns3::TcpSocketFactory::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: tcp-socket-factory.cc:29
min
#define min(a, b)
Definition: 80211b.c:42
ns3::Packet::GetSize
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:852
ns3::Packet::AddHeader
void AddHeader(const Header &header)
Add header to this packet.
Definition: packet.cc:256
ns3::BulkSendApplication::StopApplication
virtual void StopApplication(void)
Application specific shutdown code.
Definition: bulk-send-application.cc:188
ns3::MakeAddressAccessor
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
ns3::Packet::CreateFragment
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:227
ns3::Simulator::Now
static Time Now(void)
Return the current simulation virtual time.
Definition: simulator.cc:195
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ns3::Socket::GetSocketType
virtual enum Socket::SocketType GetSocketType(void) const =0
ns3::SeqTsHeader::SetSeq
void SetSeq(uint32_t seq)
Definition: seq-ts-header.cc:41
ns3::AddressValue
AttributeValue implementation for Address.
Definition: address.h:278
ns3::BulkSendApplication::m_peer
Address m_peer
Peer address.
Definition: bulk-send-application.h:124
bulk-send-application.h
NS_LOG_WARN
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:265
ns3::Socket::SetConnectCallback
void SetConnectCallback(Callback< void, Ptr< Socket > > connectionSucceeded, Callback< void, Ptr< Socket > > connectionFailed)
Specify callbacks to allow the caller to determine if the connection succeeds of fails.
Definition: socket.cc:84
ns3::Socket::Bind6
virtual int Bind6()=0
Allocate a local IPv6 endpoint for this socket.
ns3::Application::DoDispose
virtual void DoDispose(void)
Destructor implementation.
Definition: application.cc:83
ns3::Socket::SetSendCallback
void SetSendCallback(Callback< void, Ptr< Socket >, uint32_t > sendCb)
Notify application when space in transmit buffer is added.
Definition: socket.cc:121
ns3::MakeBooleanAccessor
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
ns3::BulkSendApplication::ConnectionSucceeded
void ConnectionSucceeded(Ptr< Socket > socket)
Connection Succeeded (called by Socket through a callback)
Definition: bulk-send-application.cc:289
ns3::TypeId::SetParent
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:923
ns3::MakeTraceSourceAccessor
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Definition: trace-source-accessor.h:202
ns3::Ptr< Socket >
NS_FATAL_ERROR
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:165
ns3::MakeAddressChecker
Ptr< const AttributeChecker > MakeAddressChecker(void)
Definition: address.cc:172
ns3::Socket::Send
virtual int Send(Ptr< Packet > p, uint32_t flags)=0
Send data (or dummy data) to the remote host.
ns3::BulkSendApplication::m_enableSeqTsSizeHeader
bool m_enableSeqTsSizeHeader
Enable or disable the SeqTsSizeHeader.
Definition: bulk-send-application.h:133
ns3::BulkSendApplication::GetTypeId
static TypeId GetTypeId(void)
Get the type ID.
Definition: bulk-send-application.cc:42
ns3::BulkSendApplication::DataSend
void DataSend(Ptr< Socket > socket, uint32_t unused)
Send more data as soon as some has been transmitted.
Definition: bulk-send-application.cc:306
ns3::TypeIdValue
AttributeValue implementation for TypeId.
Definition: type-id.h:595
ns3::BulkSendApplication::m_totBytes
uint64_t m_totBytes
Total bytes sent so far.
Definition: bulk-send-application.h:129
ns3::Address
a polymophic address class
Definition: address.h:91
ns3::BulkSendApplication::SetMaxBytes
void SetMaxBytes(uint64_t maxBytes)
Set the upper bound for the total number of bytes to send.
Definition: bulk-send-application.cc:104
ns3::BulkSendApplication::m_maxBytes
uint64_t m_maxBytes
Limit total number of bytes sent.
Definition: bulk-send-application.h:128
ns3::MakeBooleanChecker
Ptr< const AttributeChecker > MakeBooleanChecker(void)
Definition: boolean.cc:121
ns3::Socket::Close
virtual int Close(void)=0
Close a socket.
ns3::BulkSendApplication
Send as much traffic as possible, trying to fill the bandwidth.
Definition: bulk-send-application.h:76
NS_ABORT_MSG_IF
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition: abort.h:108
ns3::SeqTsSizeHeader::SetSize
void SetSize(uint64_t size)
Set the size information that the header will carry.
Definition: seq-ts-size-header.cc:55
ns3::MakeCallback
Callback< R, Ts... > MakeCallback(R(T::*memPtr)(Ts...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:1642
NS_LOG_LOGIC
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:289
ns3::Socket::GetPeerName
virtual int GetPeerName(Address &address) const =0
Get the peer address of a connected socket.
NS_ABORT_IF
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:77
ns3::BulkSendApplication::m_sendSize
uint32_t m_sendSize
Size of data to send each time.
Definition: bulk-send-application.h:127
ns3::BulkSendApplication::~BulkSendApplication
virtual ~BulkSendApplication()
Definition: bulk-send-application.cc:98
ns3::Socket::NS3_SOCK_SEQPACKET
@ NS3_SOCK_SEQPACKET
Definition: socket.h:106
ns3::BulkSendApplication::m_unsentPacket
Ptr< Packet > m_unsentPacket
Variable to cache unsent packet.
Definition: bulk-send-application.h:132
NS_LOG_DEBUG
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:273
ns3::Socket::Connect
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
ns3::Address::IsInvalid
bool IsInvalid(void) const
Definition: address.cc:68
ns3::BulkSendApplication::m_tid
TypeId m_tid
The type of protocol to use.
Definition: bulk-send-application.h:130
ns3::BulkSendApplication::m_txTrace
TracedCallback< Ptr< const Packet > > m_txTrace
Traced Callback: sent packets.
Definition: bulk-send-application.h:136
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition: log-macros-enabled.h:244
ns3::BulkSendApplication::m_connected
bool m_connected
True if connected.
Definition: bulk-send-application.h:126
ns3::BulkSendApplication::m_socket
Ptr< Socket > m_socket
Associated socket.
Definition: bulk-send-application.h:123
ns3::UintegerValue
Hold an unsigned integer type.
Definition: uinteger.h:44
ns3::Application::GetNode
Ptr< Node > GetNode() const
Definition: application.cc:104
ns3::Socket::CreateSocket
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
ns3::BulkSendApplication::GetSocket
Ptr< Socket > GetSocket(void) const
Get the socket this application is attached to.
Definition: bulk-send-application.cc:111
ns3::BulkSendApplication::m_local
Address m_local
Local address to bind to.
Definition: bulk-send-application.h:125
ns3::MakeUintegerAccessor
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
ns3::Application
The base class for all ns3 applications.
Definition: application.h:61
ns3::BulkSendApplication::DoDispose
virtual void DoDispose(void)
Destructor implementation.
Definition: bulk-send-application.cc:118
ns3::Socket::GetSockName
virtual int GetSockName(Address &address) const =0
Get socket address.
ns3::BulkSendApplication::m_seq
uint32_t m_seq
Sequence.
Definition: bulk-send-application.h:131
ns3::BulkSendApplication::BulkSendApplication
BulkSendApplication()
Definition: bulk-send-application.cc:89
ns3::BulkSendApplication::StartApplication
virtual void StartApplication(void)
Application specific startup code.
Definition: bulk-send-application.cc:129
ns3::BulkSendApplication::SendData
void SendData(const Address &from, const Address &to)
Send data until the L4 transmission buffer is full.
Definition: bulk-send-application.cc:206
ns3::Socket::ShutdownRecv
virtual int ShutdownRecv(void)=0
ns3::MakeTypeIdChecker
Ptr< const AttributeChecker > MakeTypeIdChecker(void)
Definition: type-id.cc:1227
ns3::MakeTypeIdAccessor
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
Definition: type-id.h:595
ns3::BulkSendApplication::m_txTraceWithSeqTsSize
TracedCallback< Ptr< const Packet >, const Address &, const Address &, const SeqTsSizeHeader & > m_txTraceWithSeqTsSize
Callback for tracing the packet Tx events, includes source, destination, the packet sent,...
Definition: bulk-send-application.h:139
ns3::Socket::NS3_SOCK_STREAM
@ NS3_SOCK_STREAM
Definition: socket.h:105