A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
48 // The number of bytes to send in this simulation.
49 static const uint32_t totalTxBytes = 2000000;
50 static uint32_t currentTxBytes = 0;
51 // Perform series of 1040 byte writes (this is a multiple of 26 since
52 // we want to detect data splicing in the output stream)
53 static const uint32_t writeSize = 1040;
54 uint8_t data[writeSize];
55 
56 // These are for starting the writing process, and handling the sending
57 // socket's notification upcalls (events). These two together more or less
58 // implement a sending "Application", although not a proper ns3::Application
59 // subclass.
60 
61 void StartFlow (Ptr<Socket>, Ipv4Address, uint16_t);
62 void WriteUntilBufferFull (Ptr<Socket>, uint32_t);
63 
64 static void
65 CwndTracer (uint32_t oldval, uint32_t newval)
66 {
67  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
68 }
69 
70 int main (int argc, char *argv[])
71 {
72  // Users may find it convenient to turn on explicit debugging
73  // for selected modules; the below lines suggest how to do this
74  // LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
75  // LogComponentEnable("TcpSocketImpl", LOG_LEVEL_ALL);
76  // LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
77  // LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
78 
79  CommandLine cmd;
80  cmd.Parse (argc, argv);
81 
82  // initialize the tx buffer.
83  for(uint32_t i = 0; i < writeSize; ++i)
84  {
85  char m = toascii (97 + i % 26);
86  data[i] = m;
87  }
88 
89  // Here, we will explicitly create three nodes. The first container contains
90  // nodes 0 and 1 from the diagram above, and the second one contains nodes
91  // 1 and 2. This reflects the channel connectivity, and will be used to
92  // install the network interfaces and connect them with a channel.
93  NodeContainer n0n1;
94  n0n1.Create (2);
95 
97  n1n2.Add (n0n1.Get (1));
98  n1n2.Create (1);
99 
100  // We create the channels first without any IP addressing information
101  // First make and configure the helper, so that it will put the appropriate
102  // attributes on the network interfaces and channels we are about to install.
103  PointToPointHelper p2p;
104  p2p.SetDeviceAttribute ("DataRate", DataRateValue (DataRate (10000000)));
105  p2p.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (10)));
106 
107  // And then install devices and channels connecting our topology.
108  NetDeviceContainer dev0 = p2p.Install (n0n1);
109  NetDeviceContainer dev1 = p2p.Install (n1n2);
110 
111  // Now add ip/tcp stack to all nodes.
112  InternetStackHelper internet;
113  internet.InstallAll ();
114 
115  // Later, we add IP addresses.
116  Ipv4AddressHelper ipv4;
117  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
118  ipv4.Assign (dev0);
119  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
120  Ipv4InterfaceContainer ipInterfs = ipv4.Assign (dev1);
121 
122  // and setup ip routing tables to get total ip-level connectivity.
124 
126  // Simulation 1
127  //
128  // Send 2000000 bytes over a connection to server port 50000 at time 0
129  // Should observe SYN exchange, a lot of data segments and ACKS, and FIN
130  // exchange. FIN exchange isn't quite compliant with TCP spec (see release
131  // notes for more info)
132  //
134 
135  uint16_t servPort = 50000;
136 
137  // Create a packet sink to receive these packets on n2...
138  PacketSinkHelper sink ("ns3::TcpSocketFactory",
139  InetSocketAddress (Ipv4Address::GetAny (), servPort));
140 
141  ApplicationContainer apps = sink.Install (n1n2.Get (1));
142  apps.Start (Seconds (0.0));
143  apps.Stop (Seconds (3.0));
144 
145  // Create a source to send packets from n0. Instead of a full Application
146  // and the helper APIs you might see in other example files, this example
147  // will use sockets directly and register some socket callbacks as a sending
148  // "Application".
149 
150  // Create and bind the socket...
151  Ptr<Socket> localSocket =
153  localSocket->Bind ();
154 
155  // Trace changes to the congestion window
156  Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));
157 
158  // ...and schedule the sending "Application"; This is similar to what an
159  // ns3::Application subclass would do internally.
160  Simulator::ScheduleNow (&StartFlow, localSocket,
161  ipInterfs.GetAddress (1), servPort);
162 
163  // One can toggle the comment for the following line on or off to see the
164  // effects of finite send buffer modelling. One can also change the size of
165  // said buffer.
166 
167  //localSocket->SetAttribute("SndBufSize", UintegerValue(4096));
168 
169  //Ask for ASCII and pcap traces of network traffic
170  AsciiTraceHelper ascii;
171  p2p.EnableAsciiAll (ascii.CreateFileStream ("tcp-large-transfer.tr"));
172  p2p.EnablePcapAll ("tcp-large-transfer");
173 
174  // Finally, set up the simulator to run. The 1000 second hard limit is a
175  // failsafe in case some change above causes the simulation to never end
176  Simulator::Stop (Seconds (1000));
177  Simulator::Run ();
179 }
180 
181 
182 //-----------------------------------------------------------------------------
183 //-----------------------------------------------------------------------------
184 //-----------------------------------------------------------------------------
185 //begin implementation of sending "Application"
186 void StartFlow (Ptr<Socket> localSocket,
187  Ipv4Address servAddress,
188  uint16_t servPort)
189 {
190  NS_LOG_LOGIC ("Starting flow at time " << Simulator::Now ().GetSeconds ());
191  localSocket->Connect (InetSocketAddress (servAddress, servPort)); //connect
192 
193  // tell the tcp implementation to call WriteUntilBufferFull again
194  // if we blocked and new tx buffer space becomes available
196  WriteUntilBufferFull (localSocket, localSocket->GetTxAvailable ());
197 }
198 
199 void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t txSpace)
200 {
201  while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0)
202  {
203  uint32_t left = totalTxBytes - currentTxBytes;
204  uint32_t dataOffset = currentTxBytes % writeSize;
205  uint32_t toWrite = writeSize - dataOffset;
206  toWrite = std::min (toWrite, left);
207  toWrite = std::min (toWrite, localSocket->GetTxAvailable ());
208  int amountSent = localSocket->Send (&data[dataOffset], toWrite, 0);
209  if(amountSent < 0)
210  {
211  // we will be called again when new tx space becomes available.
212  return;
213  }
214  currentTxBytes += amountSent;
215  }
216  localSocket->Close ();
217 }
holds a vector of ns3::Application pointers.
Manage ASCII trace files for device models.
Definition: trace-helper.h:141
an Inet address class
static Ipv4Address GetAny(void)
NodeContainer n1n2
Definition: red-tests.cc:63
holds a vector of std::pair of Ptr and interface index.
static void PopulateRoutingTables(void)
Build a routing database and initialize the routing tables of the nodes in the simulation.
NetDeviceContainer Install(NodeContainer c)
void StartFlow(Ptr< Socket >, Ipv4Address, uint16_t)
static void Run(void)
Run the simulation until one of:
Definition: simulator.cc:157
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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:223
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
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:71
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)
void InstallAll(void) const
Aggregate IPv4, IPv6, UDP, and TCP stacks to all nodes in the simulation.
hold objects of type ns3::Time
Definition: nstime.h:1008
holds a vector of ns3::NetDevice pointers
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
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:70
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:177
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
static void Destroy(void)
Every event scheduled by the Simulator::insertAtDestroy method is invoked.
Definition: simulator.cc:121
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.
keep track of a set of node pointers.
static EventId ScheduleNow(MEM mem_ptr, OBJ obj)
Schedule an event to expire Now.
Definition: simulator.h:986
static Time Now(void)
Return the "current simulation time".
Definition: simulator.cc:180
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:120
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
int main(int argc, char *argv[])
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
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.
hold objects of type ns3::DataRate
static void Stop(void)
If an event invokes this method, it will be the last event scheduled by the Simulator::run method bef...
Definition: simulator.cc:165
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
ApplicationContainer Install(NodeContainer c) const
Install an ns3::PacketSinkApplication on each node of the input container configured with all the att...
void Parse(int argc, char *argv[])
Parse the program arguments.
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
void ConnectWithoutContext(std::string path, const CallbackBase &cb)
Definition: config.cc:717
void SetBase(Ipv4Address network, Ipv4Mask mask, Ipv4Address base="0.0.0.1")
Set the base network number, network mask and base address.
Ipv4Address GetAddress(uint32_t i, uint32_t j=0) const