A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-large-transfer.cc
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: GPL-2.0-only
3 *
4 */
5
6//
7// Network topology
8//
9// 10Mb/s, 10ms 10Mb/s, 10ms
10// n0-----------------n1-----------------n2
11//
12//
13// - Tracing of queues and packet receptions to file
14// "tcp-large-transfer.tr"
15// - pcap traces also generated in the following files
16// "tcp-large-transfer-$n-$i.pcap" where n and i represent node and interface
17// numbers respectively
18// Usage (e.g.): ./ns3 run tcp-large-transfer
19
20#include "ns3/applications-module.h"
21#include "ns3/core-module.h"
22#include "ns3/internet-module.h"
23#include "ns3/ipv4-global-routing-helper.h"
24#include "ns3/network-module.h"
25#include "ns3/point-to-point-module.h"
26
27#include <fstream>
28#include <iostream>
29#include <string>
30
31using namespace ns3;
32
33NS_LOG_COMPONENT_DEFINE("TcpLargeTransfer");
34
35/// The number of bytes to send in this simulation.
36static const uint32_t totalTxBytes = 2000000;
37/// The actual number of sent bytes.
39
40// Perform series of 1040 byte writes (this is a multiple of 26 since
41// we want to detect data splicing in the output stream)
42/// Write size.
43static const uint32_t writeSize = 1040;
44/// Data to be written.
45uint8_t data[writeSize];
46
47// These are for starting the writing process, and handling the sending
48// socket's notification upcalls (events). These two together more or less
49// implement a sending "Application", although not a proper ns3::Application
50// subclass.
51
52/**
53 * Start a flow.
54 *
55 * \param localSocket The local (sending) socket.
56 * \param servAddress The server address.
57 * \param servPort The server port.
58 */
59void StartFlow(Ptr<Socket> localSocket, Ipv4Address servAddress, uint16_t servPort);
60
61/**
62 * Write to the buffer, filling it.
63 *
64 * \param localSocket The socket.
65 * \param txSpace The number of bytes to write.
66 */
67void WriteUntilBufferFull(Ptr<Socket> localSocket, uint32_t txSpace);
68
69/**
70 * Congestion window tracker function.
71 *
72 * \param oldval Old value.
73 * \param newval New value.
74 */
75static void
77{
78 NS_LOG_INFO("Moving cwnd from " << oldval << " to " << newval);
79}
80
81int
82main(int argc, char* argv[])
83{
84 // Users may find it convenient to turn on explicit debugging
85 // for selected modules; the below lines suggest how to do this
86 // LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
87 // LogComponentEnable("TcpSocketImpl", LOG_LEVEL_ALL);
88 // LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
89 // LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
90
91 CommandLine cmd(__FILE__);
92 cmd.Parse(argc, argv);
93
94 // initialize the tx buffer.
95 for (uint32_t i = 0; i < writeSize; ++i)
96 {
97 char m = toascii(97 + i % 26);
98 data[i] = m;
99 }
100
101 // Here, we will explicitly create three nodes. The first container contains
102 // nodes 0 and 1 from the diagram above, and the second one contains nodes
103 // 1 and 2. This reflects the channel connectivity, and will be used to
104 // install the network interfaces and connect them with a channel.
105 NodeContainer n0n1;
106 n0n1.Create(2);
107
109 n1n2.Add(n0n1.Get(1));
110 n1n2.Create(1);
111
112 // We create the channels first without any IP addressing information
113 // First make and configure the helper, so that it will put the appropriate
114 // attributes on the network interfaces and channels we are about to install.
116 p2p.SetDeviceAttribute("DataRate", DataRateValue(DataRate(10000000)));
117 p2p.SetChannelAttribute("Delay", TimeValue(MilliSeconds(10)));
118
119 // And then install devices and channels connecting our topology.
120 NetDeviceContainer dev0 = p2p.Install(n0n1);
121 NetDeviceContainer dev1 = p2p.Install(n1n2);
122
123 // Now add ip/tcp stack to all nodes.
125 internet.InstallAll();
126
127 // Later, we add IP addresses.
129 ipv4.SetBase("10.1.3.0", "255.255.255.0");
130 ipv4.Assign(dev0);
131 ipv4.SetBase("10.1.2.0", "255.255.255.0");
132 Ipv4InterfaceContainer ipInterfs = ipv4.Assign(dev1);
133
134 // and setup ip routing tables to get total ip-level connectivity.
136
137 ///////////////////////////////////////////////////////////////////////////
138 // Simulation 1
139 //
140 // Send 2000000 bytes over a connection to server port 50000 at time 0
141 // Should observe SYN exchange, a lot of data segments and ACKS, and FIN
142 // exchange. FIN exchange isn't quite compliant with TCP spec (see release
143 // notes for more info)
144 //
145 ///////////////////////////////////////////////////////////////////////////
146
147 uint16_t servPort = 50000;
148
149 // Create a packet sink to receive these packets on n2...
150 PacketSinkHelper sink("ns3::TcpSocketFactory",
152
153 ApplicationContainer apps = sink.Install(n1n2.Get(1));
154 apps.Start(Seconds(0.0));
155 apps.Stop(Seconds(3.0));
156
157 // Create a source to send packets from n0. Instead of a full Application
158 // and the helper APIs you might see in other example files, this example
159 // will use sockets directly and register some socket callbacks as a sending
160 // "Application".
161
162 // Create and bind the socket...
164 localSocket->Bind();
165
166 // Trace changes to the congestion window
167 Config::ConnectWithoutContext("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
169
170 // ...and schedule the sending "Application"; This is similar to what an
171 // ns3::Application subclass would do internally.
172 Simulator::ScheduleNow(&StartFlow, localSocket, ipInterfs.GetAddress(1), servPort);
173
174 // One can toggle the comment for the following line on or off to see the
175 // effects of finite send buffer modelling. One can also change the size of
176 // said buffer.
177
178 // localSocket->SetAttribute("SndBufSize", UintegerValue(4096));
179
180 // Ask for ASCII and pcap traces of network traffic
181 AsciiTraceHelper ascii;
182 p2p.EnableAsciiAll(ascii.CreateFileStream("tcp-large-transfer.tr"));
183 p2p.EnablePcapAll("tcp-large-transfer");
184
185 // Finally, set up the simulator to run. The 1000 second hard limit is a
186 // failsafe in case some change above causes the simulation to never end
190
191 return 0;
192}
193
194//-----------------------------------------------------------------------------
195//-----------------------------------------------------------------------------
196//-----------------------------------------------------------------------------
197// begin implementation of sending "Application"
198void
199StartFlow(Ptr<Socket> localSocket, Ipv4Address servAddress, uint16_t servPort)
200{
201 NS_LOG_LOGIC("Starting flow at time " << Simulator::Now().GetSeconds());
202 localSocket->Connect(InetSocketAddress(servAddress, servPort)); // connect
203
204 // tell the tcp implementation to call WriteUntilBufferFull again
205 // if we blocked and new tx buffer space becomes available
206 localSocket->SetSendCallback(MakeCallback(&WriteUntilBufferFull));
207 WriteUntilBufferFull(localSocket, localSocket->GetTxAvailable());
208}
209
210void
212{
213 while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable() > 0)
214 {
216 uint32_t dataOffset = currentTxBytes % writeSize;
217 uint32_t toWrite = writeSize - dataOffset;
218 toWrite = std::min(toWrite, left);
219 toWrite = std::min(toWrite, localSocket->GetTxAvailable());
220 int amountSent = localSocket->Send(&data[dataOffset], toWrite, 0);
221 if (amountSent < 0)
222 {
223 // we will be called again when new tx space becomes available.
224 return;
225 }
226 currentTxBytes += amountSent;
227 }
229 {
230 localSocket->Close();
231 }
232}
NodeContainer n1n2
Nodecontainer n1 + n2.
holds a vector of ns3::Application pointers.
void Start(Time start) const
Start all of the Applications in this container at the start time given as a parameter.
void Stop(Time stop) const
Arrange for all of the Applications in this container to Stop() at the Time given as a parameter.
Manage ASCII trace files for device models.
Ptr< OutputStreamWrapper > CreateFileStream(std::string filename, std::ios::openmode filemode=std::ios::out)
Create and initialize an output stream object we'll use to write the traced bits.
Parse command-line arguments.
Class for representing data rates.
Definition data-rate.h:78
an Inet address class
aggregate IP/TCP/UDP functionality to existing Nodes.
A helper class to make life easier while doing simple IPv4 address assignment in scripts.
Ipv4 addresses are stored in host order in this class.
static Ipv4Address GetAny()
static void PopulateRoutingTables()
Build a routing database and initialize the routing tables of the nodes in the simulation.
holds a vector of std::pair of Ptr<Ipv4> and interface index.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const
holds a vector of ns3::NetDevice pointers
keep track of a set of node pointers.
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
void Add(const NodeContainer &nc)
Append the contents of another NodeContainer to the end of this container.
Ptr< Node > Get(uint32_t i) const
Get the Ptr<Node> stored in this container at a given index.
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes.
Build a set of PointToPointNetDevice objects.
Smart pointer class similar to boost::intrusive_ptr.
static void Destroy()
Execute the events scheduled with ScheduleDestroy().
Definition simulator.cc:131
static Time Now()
Return the current simulation virtual time.
Definition simulator.cc:197
static void Run()
Run the simulation.
Definition simulator.cc:167
static EventId ScheduleNow(FUNC f, Ts &&... args)
Schedule an event to expire Now.
Definition simulator.h:594
static void Stop()
Tell the Simulator the calling event should be the last one executed.
Definition simulator.cc:175
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
static TypeId GetTypeId()
Get the type ID.
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition config.cc:943
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition log.h:264
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition nstime.h:1308
Time MilliSeconds(uint64_t value)
Construct a Time in the indicated unit.
Definition nstime.h:1320
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
static const uint32_t totalTxBytes
The number of bytes to send in this simulation.
void StartFlow(Ptr< Socket > localSocket, Ipv4Address servAddress, uint16_t servPort)
Start a flow.
static const uint32_t writeSize
Write size.
static uint32_t currentTxBytes
The actual number of sent bytes.
static void CwndTracer(uint32_t oldval, uint32_t newval)
Congestion window tracker function.
uint8_t data[writeSize]
Data to be written.
void WriteUntilBufferFull(Ptr< Socket > localSocket, uint32_t txSpace)
Write to the buffer, filling it.
Ptr< PacketSink > sink
Pointer to the packet sink application.
Definition wifi-tcp.cc:44