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