A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
bulk-send-application.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010 Georgia Institute of Technology
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: George F. Riley <riley@ece.gatech.edu>
7 */
8
10
11#include "ns3/boolean.h"
12#include "ns3/log.h"
13#include "ns3/node.h"
14#include "ns3/nstime.h"
15#include "ns3/packet.h"
16#include "ns3/simulator.h"
17#include "ns3/socket-factory.h"
18#include "ns3/socket.h"
19#include "ns3/tcp-socket-base.h"
20#include "ns3/tcp-socket-factory.h"
21#include "ns3/trace-source-accessor.h"
22#include "ns3/uinteger.h"
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("BulkSendApplication");
28
30
33{
34 static TypeId tid =
35 TypeId("ns3::BulkSendApplication")
37 .SetGroupName("Applications")
38 .AddConstructor<BulkSendApplication>()
39 .AddAttribute("SendSize",
40 "The amount of data to send each time.",
41 UintegerValue(512),
44 .AddAttribute("MaxBytes",
45 "The total number of bytes to send. "
46 "Once these bytes are sent, "
47 "no data is sent again. The value zero means "
48 "that there is no limit.",
52 .AddAttribute("Protocol",
53 "The type of protocol to use.",
57 .AddAttribute("EnableSeqTsSizeHeader",
58 "Add SeqTsSizeHeader to each packet",
59 BooleanValue(false),
62 .AddTraceSource("TxWithSeqTsSize",
63 "A new packet is created with SeqTsSizeHeader",
65 "ns3::PacketSink::SeqTsSizeCallback")
66 .AddTraceSource("TcpRetransmission",
67 "The TCP socket retransmitted a packet",
69 "ns3::TcpSocketBase::RetransmissionCallback");
70
71 return tid;
72}
73
78
83
84void
86{
87 NS_LOG_FUNCTION(this << maxBytes);
88 m_maxBytes = maxBytes;
89}
90
91void
97
98// Application Methods
99void
100BulkSendApplication::DoStartApplication() // Called at time specified by Start
101{
102 NS_LOG_FUNCTION(this);
103
104 // Fatal error if socket type is not NS3_SOCK_STREAM or NS3_SOCK_SEQPACKET
105 if (m_socket->GetSocketType() != Socket::NS3_SOCK_STREAM &&
106 m_socket->GetSocketType() != Socket::NS3_SOCK_SEQPACKET)
107 {
108 NS_FATAL_ERROR("Using BulkSend with an incompatible socket type. "
109 "BulkSend requires SOCK_STREAM or SOCK_SEQPACKET. "
110 "In other words, use TCP instead of UDP.");
111 }
112
113 m_socket->ShutdownRecv();
114 m_socket->SetSendCallback(MakeCallback(&BulkSendApplication::DataSend, this));
115
116 if (auto tcpSocket = DynamicCast<TcpSocketBase>(m_socket))
117 {
118 tcpSocket->TraceConnectWithoutContext(
119 "Retransmission",
121 }
122
123 if (m_connected)
124 {
125 Address from;
126 m_socket->GetSockName(from);
127 SendData(from, m_peer);
128 }
129}
130
131// Private helpers
132
133void
135{
136 NS_LOG_FUNCTION(this);
137
138 while (m_maxBytes == 0 || m_totBytes < m_maxBytes)
139 { // Time to send more
140
141 // uint64_t to allow the comparison later.
142 // the result is in a uint32_t range anyway, because
143 // m_sendSize is uint32_t.
144 uint64_t toSend = m_sendSize;
145 // Make sure we don't send too many
146 if (m_maxBytes > 0)
147 {
148 toSend = std::min(toSend, m_maxBytes - m_totBytes);
149 }
150
151 NS_LOG_LOGIC("sending packet at " << Simulator::Now());
152
153 Ptr<Packet> packet;
154 if (m_unsentPacket)
155 {
156 packet = m_unsentPacket;
157 toSend = packet->GetSize();
158 }
160 {
161 SeqTsSizeHeader header;
162 header.SetSeq(m_seq++);
163 header.SetSize(toSend);
164 NS_ABORT_IF(toSend < header.GetSerializedSize());
165 packet = Create<Packet>(toSend - header.GetSerializedSize());
166 // Trace before adding header, for consistency with PacketSink
167 m_txTraceWithSeqTsSize(packet, from, to, header);
168 packet->AddHeader(header);
169 }
170 else
171 {
172 packet = Create<Packet>(toSend);
173 }
174
175 int actual = m_socket->Send(packet);
176 if ((unsigned)actual == toSend)
177 {
178 m_totBytes += actual;
179 m_txTrace(packet);
180 m_unsentPacket = nullptr;
181 }
182 else if (actual == -1)
183 {
184 // We exit this loop when actual < toSend as the send side
185 // buffer is full. The "DataSent" callback will pop when
186 // some buffer space has freed up.
187 NS_LOG_DEBUG("Unable to send packet; caching for later attempt");
188 m_unsentPacket = packet;
189 break;
190 }
191 else if (actual > 0 && (unsigned)actual < toSend)
192 {
193 // A Linux socket (non-blocking, such as in DCE) may return
194 // a quantity less than the packet size. Split the packet
195 // into two, trace the sent packet, save the unsent packet
196 NS_LOG_DEBUG("Packet size: " << packet->GetSize() << "; sent: " << actual
197 << "; fragment saved: " << toSend - (unsigned)actual);
198 Ptr<Packet> sent = packet->CreateFragment(0, actual);
199 Ptr<Packet> unsent = packet->CreateFragment(actual, (toSend - (unsigned)actual));
200 m_totBytes += actual;
201 m_txTrace(sent);
202 m_unsentPacket = unsent;
203 break;
204 }
205 else
206 {
207 NS_FATAL_ERROR("Unexpected return value from m_socket->Send ()");
208 }
209 }
210 // Check if time to close (all sent)
212 {
213 m_socket->Close();
214 m_connected = false;
215 }
216}
217
218void
220{
221 NS_LOG_FUNCTION(this << socket);
222 NS_LOG_LOGIC("BulkSendApplication Connection succeeded");
223 Address from;
224 Address to;
225 socket->GetSockName(from);
226 socket->GetPeerName(to);
227 SendData(from, to);
228}
229
230void
232{
233 NS_LOG_FUNCTION(this);
234
235 if (m_connected)
236 { // Only send new data if the connection has completed
237 Address from;
238 Address to;
239 socket->GetSockName(from);
240 socket->GetPeerName(to);
241 SendData(from, to);
242 }
243}
244
245void
247 const TcpHeader& header,
248 const Address& localAddr,
249 const Address& peerAddr,
251{
252 NS_LOG_FUNCTION(this << p << header << localAddr << peerAddr << socket);
253 m_retransmissionTrace(p, header, localAddr, peerAddr, socket);
254}
255
256} // Namespace ns3
a polymophic address class
Definition address.h:90
AttributeValue implementation for Boolean.
Definition boolean.h:26
Send as much traffic as possible, trying to fill the bandwidth.
bool m_enableSeqTsSizeHeader
Enable or disable the SeqTsSizeHeader.
void SendData(const Address &from, const Address &to)
Send data until the L4 transmission buffer is full.
Ptr< Packet > m_unsentPacket
Variable to cache unsent packet.
void PacketRetransmitted(Ptr< const Packet > p, const TcpHeader &header, const Address &localAddr, const Address &peerAddr, Ptr< const TcpSocketBase > socket)
Packet retransmitted (called by TcpSocketBase sockets via callback).
void DoStartApplication() override
Application specific startup code for child subclasses.
void CancelEvents() override
Cancel all pending events.
static TypeId GetTypeId()
Get the type ID.
TracedCallback< Ptr< const Packet >, const TcpHeader &, const Address &, const Address &, Ptr< const TcpSocketBase > > m_retransmissionTrace
Traced Callback: retransmitted packets.
uint32_t m_sendSize
Size of data to send each time.
uint64_t m_maxBytes
Limit total number of bytes sent.
void DoConnectionSucceeded(Ptr< Socket > socket) override
Application specific code for child subclasses upon a Connection Succeed event.
uint64_t m_totBytes
Total bytes sent so far.
void DataSend(Ptr< Socket > socket, uint32_t unused)
Send more data as soon as some has been transmitted.
void SetMaxBytes(uint64_t maxBytes)
Set the upper bound for the total number of bytes to send.
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,...
Smart pointer class similar to boost::intrusive_ptr.
Definition ptr.h:67
void SetSeq(uint32_t seq)
Header with a sequence, a timestamp, and a "size" attribute.
uint32_t GetSerializedSize() const override
void SetSize(uint64_t size)
Set the size information that the header will carry.
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
@ NS3_SOCK_STREAM
Definition socket.h:97
@ NS3_SOCK_SEQPACKET
Definition socket.h:98
TypeId m_protocolTid
Protocol TypeId value.
SourceApplication(bool allowPacketSocket=true)
Constructor.
Ptr< Socket > m_socket
Socket.
TracedCallback< Ptr< const Packet > > m_txTrace
Traced Callback: transmitted packets.
bool m_connected
flag whether socket is connected
Address m_peer
Peer address.
Header for the Transmission Control Protocol.
Definition tcp-header.h:36
static TypeId GetTypeId()
Get the type ID.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
AttributeValue implementation for TypeId.
Definition type-id.h:641
Hold an unsigned integer type.
Definition uinteger.h:34
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition boolean.cc:114
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 > MakeTypeIdChecker()
Definition type-id.cc:1335
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:641
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
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#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:439
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition callback.h:684
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:585