7#include "traffic-generator.h"
9#include "ns3/address.h"
12#include "ns3/nstime.h"
13#include "ns3/packet.h"
14#include "ns3/simulator.h"
15#include "ns3/socket-factory.h"
16#include "ns3/socket.h"
17#include "ns3/tcp-socket-factory.h"
18#include "ns3/trace-source-accessor.h"
19#include "ns3/udp-socket-factory.h"
20#include "ns3/uinteger.h"
25NS_LOG_COMPONENT_DEFINE(
"TrafficGenerator");
26NS_OBJECT_ENSURE_REGISTERED(TrafficGenerator);
28uint16_t TrafficGenerator::m_tgIdCounter = 0;
34 TypeId(
"ns3::TrafficGenerator").SetParent<Application>().SetGroupName(
"Applications");
38TrafficGenerator::TrafficGenerator()
42 m_currentBurstTotBytes(0),
43 m_currentBurstTotPackets(0),
48 NS_LOG_FUNCTION(
this);
49 m_tgId = m_tgIdCounter++;
52TrafficGenerator::~TrafficGenerator()
54 NS_LOG_FUNCTION(
this);
60 NS_LOG_FUNCTION(
this);
67 NS_LOG_FUNCTION(
this);
74 NS_LOG_FUNCTION(
this);
79TrafficGenerator::GenerateNextPacketBurstSize()
81 NS_LOG_FUNCTION(
this);
82 m_packetBurstSizeInBytes = 0;
83 m_packetBurstSizeInPackets = 0;
87TrafficGenerator::DoDispose()
89 NS_LOG_FUNCTION(
this);
92 Application::DoDispose();
96TrafficGenerator::DoInitialize()
98 NS_LOG_FUNCTION(
this);
99 Application::DoInitialize();
105 NS_LOG_FUNCTION(
this);
107 m_waitForNextPacketBurst =
false;
111 NS_LOG_INFO(
"Ignore SendPacketBurst because the application is stopped.");
115 m_currentBurstTotBytes = 0;
116 m_currentBurstTotPackets = 0;
120 NS_LOG_FUNCTION(
"Socket exists");
124 m_socket = Socket::CreateSocket(GetNode(), m_tid);
125 if (Inet6SocketAddress::IsMatchingType(m_peer))
129 else if (InetSocketAddress::IsMatchingType(m_peer))
135 NS_LOG_UNCOND(
"Could not bind the socket.");
137 int connectRes = m_socket->Connect(m_peer);
138 NS_ABORT_MSG_UNLESS(connectRes == 0,
139 "Error in connecting the socket to the peer address:" << m_peer);
140 m_socket->ShutdownRecv();
141 m_socket->SetConnectCallback(MakeCallback(&TrafficGenerator::ConnectionSucceeded,
this),
142 MakeCallback(&TrafficGenerator::ConnectionFailed,
this));
143 m_socket->SetSendCallback(MakeCallback(&TrafficGenerator::SendNextPacketIfConnected,
this));
144 m_socket->SetCloseCallbacks(MakeCallback(&TrafficGenerator::CloseSucceeded,
this),
145 MakeCallback(&TrafficGenerator::CloseFailed,
this));
148 if (m_connected || m_tid == UdpSocketFactory::GetTypeId())
150 GenerateNextPacketBurstSize();
152 if (m_packetBurstSizeInBytes != 0)
154 NS_LOG_LOGIC(
"Starting transfer of packet burst of size " << m_packetBurstSizeInBytes);
159 "Starting transfer of packet burst of unknown size, that will contain at least: "
160 << m_packetBurstSizeInPackets <<
" packets");
165 if (m_eventIdSendNextPacket.IsPending())
167 m_eventIdSendNextPacket.Cancel();
168 NS_LOG_WARN(
"Canceling next packet send");
174 NS_LOG_UNCOND(
this <<
" Not connected yet. Expected if you are using TCP socket because "
175 "TCP handshake needs to complete...");
183TrafficGenerator::StartApplication()
185 NS_LOG_FUNCTION(
this);
189TrafficGenerator::StopApplication()
191 NS_LOG_FUNCTION(
this);
192 NS_LOG_LOGIC(
"TrafficGenerator closing socket");
194 if (!(m_connected || m_tid == UdpSocketFactory::GetTypeId()))
196 NS_LOG_WARN(
"Stopping the application that never started. Which could happen if the "
197 "protocol used is TCP and the connection never got established.");
205 NS_LOG_WARN(
"TrafficGenerator found null socket to close in StopApplication");
209 if (m_tid == UdpSocketFactory::GetTypeId())
220 NS_LOG_INFO(
"Sent packets: " << m_totPackets <<
" and the total bytes: " << m_totBytes);
224TrafficGenerator::SetPacketBurstSizeInBytes(uint32_t burstSize)
226 m_packetBurstSizeInBytes = burstSize;
230TrafficGenerator::SetPacketBurstSizeInPackets(uint32_t burstSize)
232 m_packetBurstSizeInPackets = burstSize;
236TrafficGenerator::GetPacketBurstSizeInBytes()
const
238 return m_packetBurstSizeInBytes;
242TrafficGenerator::GetPacketBurstSizeInPackets()
const
244 return m_packetBurstSizeInPackets;
248TrafficGenerator::SendNextPacket()
252 NS_LOG_WARN(
"Ignore SendNextPacket because the application is stopped.");
257 NS_LOG_DEBUG(
"Socket closed. Ignoring the call for send next packet.");
261 if (m_packetBurstSizeInBytes == 0 && m_packetBurstSizeInPackets == 0)
263 GenerateNextPacketBurstSize();
266 NS_ASSERT(m_packetBurstSizeInBytes || m_packetBurstSizeInPackets);
269 uint32_t toSend = GetNextPacketSize();
271 if ((m_packetBurstSizeInBytes > 0) and
272 (m_packetBurstSizeInBytes - m_currentBurstTotBytes > toSend))
274 toSend = std::min(toSend, m_packetBurstSizeInBytes - m_currentBurstTotBytes);
275 NS_LOG_INFO(
"Sending a packet at " << Simulator::Now() <<
" of size:" << toSend);
284 if (m_socket->GetTxAvailable() > toSend)
286 Ptr<Packet> packet = Create<Packet>(toSend);
288 actual = m_socket->Send(packet);
290 NS_ASSERT(actual == (
int)(toSend));
295 m_tid == UdpSocketFactory::GetTypeId(),
296 "When using UDP socket the packet size cannot be greater than 65535, reconfigure your "
297 "application to generate packets up to this permitted size.");
299 NS_LOG_WARN(
"Unable to send packet; actual " << actual <<
" size " << toSend
300 <<
"; caching for later attempt");
302 NS_LOG_INFO(
"Sent data: " << actual <<
" bytes.");
304 if ((actual < (
int)toSend))
309 NS_LOG_DEBUG(
"Send buffer is full.");
314 m_currentBurstTotBytes += actual;
315 m_totBytes += actual;
316 m_currentBurstTotPackets++;
318 NS_LOG_INFO(
"Sending " << actual
321 << m_currentBurstTotBytes
322 <<
", and packetBurstSize: " << m_packetBurstSizeInBytes);
325 if (m_currentBurstTotBytes < m_packetBurstSizeInBytes ||
326 m_currentBurstTotPackets < m_packetBurstSizeInPackets || m_packetBurstSizeInPackets == 1)
328 Time nextPacketTime = GetNextPacketTime();
329 NS_ASSERT(nextPacketTime.GetSeconds() >= 0);
330 m_eventIdSendNextPacket =
331 Simulator::Schedule(nextPacketTime, &TrafficGenerator::SendNextPacket,
this);
335 m_currentBurstTotBytes = 0;
336 m_currentBurstTotPackets = 0;
337 m_eventIdSendNextPacket.Cancel();
338 m_waitForNextPacketBurst =
true;
344TrafficGenerator::PacketBurstSent()
346 NS_LOG_FUNCTION(
this);
350TrafficGenerator::GetNextPacketTime()
const
352 NS_LOG_FUNCTION(
this);
353 return MilliSeconds(0);
357TrafficGenerator::ConnectionSucceeded(Ptr<Socket> socket)
359 NS_LOG_FUNCTION(
this << socket);
360 NS_LOG_UNCOND(
this <<
" TrafficGenerator Connection succeeded");
364 if (!m_eventIdSendNextPacket.IsPending() && !m_waitForNextPacketBurst)
366 Time nextPacketTime = GetNextPacketTime();
367 m_eventIdSendNextPacket =
368 Simulator::Schedule(nextPacketTime, &TrafficGenerator::SendNextPacket,
this);
373TrafficGenerator::ConnectionFailed(Ptr<Socket> socket)
375 NS_LOG_FUNCTION(
this << socket);
376 NS_LOG_LOGIC(
"TrafficGenerator Connection failed");
381TrafficGenerator::CloseSucceeded(Ptr<Socket> socket)
383 NS_LOG_FUNCTION(
this << socket);
384 NS_LOG_LOGIC(
"TrafficGenerator Close succeeded");
389TrafficGenerator::CloseFailed(Ptr<Socket> socket)
391 NS_LOG_FUNCTION(
this << socket);
392 NS_LOG_LOGIC(
"TrafficGenerator Close failed");
397TrafficGenerator::SendNextPacketIfConnected(Ptr<Socket>, uint32_t)
399 NS_LOG_FUNCTION(
this);
402 if (m_connected || m_tid == UdpSocketFactory::GetTypeId())
404 NS_LOG_LOGIC(
"TrafficGenerator SendNextPacketIfConnected callback triggers new "
405 "SendNextPacket call");
407 if (!m_eventIdSendNextPacket.IsPending() && !m_waitForNextPacketBurst)
409 Time nextPacketTime = GetNextPacketTime();
410 m_eventIdSendNextPacket =
411 Simulator::Schedule(nextPacketTime, &TrafficGenerator::SendNextPacket,
this);
430TrafficGenerator::GetTgId()
const
436TrafficGenerator::GetPeer()
const
uint64_t GetTotalPackets() const
Get the total number of packets that have been sent during this object's lifetime.
void SetRemote(Address remote)
Sets the remote address.
static TypeId GetTypeId()
Get the type ID.
bool SendPacketBurst()
Send another packet burst, which can be e.g., a file, or a video frame.
int64_t AssignStreams(int64_t stream) override
void SetProtocol(TypeId protocol)
Sets the protocol.
uint64_t GetTotalBytes() const
Get the total number of bytes that have been sent during this object's lifetime.
Ptr< Socket > GetSocket() const
Get the socket this application is attached to.