A Discrete-Event Network Simulator
API
sixth.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 #include <fstream>
18 #include "ns3/core-module.h"
19 #include "ns3/network-module.h"
20 #include "ns3/internet-module.h"
21 #include "ns3/point-to-point-module.h"
22 #include "ns3/applications-module.h"
23 
24 using namespace ns3;
25 
26 NS_LOG_COMPONENT_DEFINE ("SixthScriptExample");
27 
28 // ===========================================================================
29 //
30 // node 0 node 1
31 // +----------------+ +----------------+
32 // | ns-3 TCP | | ns-3 TCP |
33 // +----------------+ +----------------+
34 // | 10.1.1.1 | | 10.1.1.2 |
35 // +----------------+ +----------------+
36 // | point-to-point | | point-to-point |
37 // +----------------+ +----------------+
38 // | |
39 // +---------------------+
40 // 5 Mbps, 2 ms
41 //
42 //
43 // We want to look at changes in the ns-3 TCP congestion window. We need
44 // to crank up a flow and hook the CongestionWindow attribute on the socket
45 // of the sender. Normally one would use an on-off application to generate a
46 // flow, but this has a couple of problems. First, the socket of the on-off
47 // application is not created until Application Start time, so we wouldn't be
48 // able to hook the socket (now) at configuration time. Second, even if we
49 // could arrange a call after start time, the socket is not public so we
50 // couldn't get at it.
51 //
52 // So, we can cook up a simple version of the on-off application that does what
53 // we want. On the plus side we don't need all of the complexity of the on-off
54 // application. On the minus side, we don't have a helper, so we have to get
55 // a little more involved in the details, but this is trivial.
56 //
57 // So first, we create a socket and do the trace connect on it; then we pass
58 // this socket into the constructor of our simple application which we then
59 // install in the source node.
60 // ===========================================================================
61 //
62 class MyApp : public Application
63 {
64 public:
65  MyApp ();
66  virtual ~MyApp ();
67 
72  static TypeId GetTypeId (void);
73  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
74 
75 private:
76  virtual void StartApplication (void);
77  virtual void StopApplication (void);
78 
79  void ScheduleTx (void);
80  void SendPacket (void);
81 
82  Ptr<Socket> m_socket;
83  Address m_peer;
84  uint32_t m_packetSize;
85  uint32_t m_nPackets;
86  DataRate m_dataRate;
87  EventId m_sendEvent;
88  bool m_running;
89  uint32_t m_packetsSent;
90 };
91 
92 MyApp::MyApp ()
93  : m_socket (0),
94  m_peer (),
95  m_packetSize (0),
96  m_nPackets (0),
97  m_dataRate (0),
98  m_sendEvent (),
99  m_running (false),
100  m_packetsSent (0)
101 {
102 }
103 
104 MyApp::~MyApp ()
105 {
106  m_socket = 0;
107 }
108 
109 /* static */
111 {
112  static TypeId tid = TypeId ("MyApp")
114  .SetGroupName ("Tutorial")
115  .AddConstructor<MyApp> ()
116  ;
117  return tid;
118 }
119 
120 void
121 MyApp::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
122 {
123  m_socket = socket;
124  m_peer = address;
126  m_nPackets = nPackets;
127  m_dataRate = dataRate;
128 }
129 
130 void
132 {
133  m_running = true;
134  m_packetsSent = 0;
135  m_socket->Bind ();
137  SendPacket ();
138 }
139 
140 void
142 {
143  m_running = false;
144 
145  if (m_sendEvent.IsRunning ())
146  {
147  Simulator::Cancel (m_sendEvent);
148  }
149 
150  if (m_socket)
151  {
152  m_socket->Close ();
153  }
154 }
155 
156 void
157 MyApp::SendPacket (void)
158 {
159  Ptr<Packet> packet = Create<Packet> (m_packetSize);
160  m_socket->Send (packet);
161 
162  if (++m_packetsSent < m_nPackets)
163  {
164  ScheduleTx ();
165  }
166 }
167 
168 void
169 MyApp::ScheduleTx (void)
170 {
171  if (m_running)
172  {
173  Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
174  m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
175  }
176 }
177 
178 static void
179 CwndChange (Ptr<OutputStreamWrapper> stream, uint32_t oldCwnd, uint32_t newCwnd)
180 {
181  NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
182  *stream->GetStream () << Simulator::Now ().GetSeconds () << "\t" << oldCwnd << "\t" << newCwnd << std::endl;
183 }
184 
185 static void
187 {
188  NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
189  file->Write (Simulator::Now (), p);
190 }
191 
192 int
193 main (int argc, char *argv[])
194 {
196  cmd.Parse (argc, argv);
197 
199  nodes.Create (2);
200 
202  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
203  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
204 
206  devices = pointToPoint.Install (nodes);
207 
208  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ();
209  em->SetAttribute ("ErrorRate", DoubleValue (0.00001));
210  devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
211 
213  stack.Install (nodes);
214 
216  address.SetBase ("10.1.1.0", "255.255.255.252");
217  Ipv4InterfaceContainer interfaces = address.Assign (devices);
218 
219  uint16_t sinkPort = 8080;
220  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
221  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
222  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
223  sinkApps.Start (Seconds (0.));
224  sinkApps.Stop (Seconds (20.));
225 
226  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
227 
228  Ptr<MyApp> app = CreateObject<MyApp> ();
229  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
230  nodes.Get (0)->AddApplication (app);
231  app->SetStartTime (Seconds (1.));
232  app->SetStopTime (Seconds (20.));
233 
234  AsciiTraceHelper asciiTraceHelper;
235  Ptr<OutputStreamWrapper> stream = asciiTraceHelper.CreateFileStream ("sixth.cwnd");
236  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeBoundCallback (&CwndChange, stream));
237 
238  PcapHelper pcapHelper;
239  Ptr<PcapFileWrapper> file = pcapHelper.CreateFile ("sixth.pcap", std::ios::out, PcapHelper::DLT_PPP);
240  devices.Get (1)->TraceConnectWithoutContext ("PhyRxDrop", MakeBoundCallback (&RxDrop, file));
241 
242  Simulator::Stop (Seconds (20));
243  Simulator::Run ();
244  Simulator::Destroy ();
245 
246  return 0;
247 }
248 
holds a vector of ns3::Application pointers.
uint32_t AddApplication(Ptr< Application > application)
Associate an Application to this Node.
Definition: node.cc:157
static void SendPacket(Ptr< Socket > socket, uint32_t pktSize, uint32_t pktCount, Time pktInterval)
tuple pointToPoint
Definition: first.py:28
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< Socket > m_socket
Definition: fifth.cc:78
Manage ASCII trace files for device models.
Definition: trace-helper.h:161
an Inet address class
tuple devices
Definition: first.py:32
holds a vector of std::pair of Ptr and interface index.
Hold variables of type string.
Definition: string.h:41
Ptr< NetDevice > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
NetDeviceContainer Install(NodeContainer c)
Manage pcap files for device models.
Definition: trace-helper.h:38
void Write(Time t, Ptr< const Packet > p)
Write the next packet to file.
Callback< R > MakeBoundCallback(R(*fnPtr)(TX), ARG a1)
Make Callbacks with one bound argument.
Definition: callback.h:1686
static void RxDrop(Ptr< PcapFileWrapper > file, Ptr< const Packet > p)
Definition: sixth.cc:186
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
aggregate IP/TCP/UDP functionality to existing Nodes.
DataRate m_dataRate
Definition: fifth.cc:82
A helper to make it easier to instantiate an ns3::PacketSinkApplication on a set of nodes...
bool IsRunning(void) const
This method is syntactic sugar for !IsExpired().
Definition: event-id.cc:65
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. ...
Build a set of PointToPointNetDevice objects.
Address m_peer
Definition: fifth.cc:79
Ptr< PcapFileWrapper > CreateFile(std::string filename, std::ios::openmode filemode, DataLinkType dataLinkType, uint32_t snapLen=std::numeric_limits< uint32_t >::max(), int32_t tzCorrection=0)
Create and initialize a pcap file.
Definition: trace-helper.cc:49
void SetDeviceAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each NetDevice created by the helper.
tuple cmd
Definition: second.py:35
a polymophic address class
Definition: address.h:90
Definition: fifth.cc:62
tuple nodes
Definition: first.py:25
Class for representing data rates.
Definition: data-rate.h:88
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
Definition: nstime.h:341
void Setup(Ptr< Socket > socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
Definition: fifth.cc:106
static void CwndChange(Ptr< OutputStreamWrapper > stream, uint32_t oldCwnd, uint32_t newCwnd)
Definition: sixth.cc:179
The base class for all ns3 applications.
Definition: application.h:60
tuple interfaces
Definition: first.py:41
holds a vector of ns3::NetDevice pointers
void SendPacket(void)
Definition: fifth.cc:142
uint32_t m_nPackets
Definition: fifth.cc:81
bool m_running
Definition: fifth.cc:84
uint32_t m_packetsSent
Definition: fifth.cc:85
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:205
virtual int Connect(const Address &address)=0
Initiate a connection to a remote host.
virtual ~MyApp()
Definition: fifth.cc:100
bool TraceConnectWithoutContext(std::string name, const CallbackBase &cb)
Connect a TraceSource to a Callback without a context.
Definition: object-base.cc:293
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.
EventId m_sendEvent
Definition: fifth.cc:83
keep track of a set of node pointers.
Hold objects of type Ptr.
Definition: pointer.h:36
uint64_t GetBitRate() const
Get the underlying bitrate.
Definition: data-rate.cc:249
void Install(std::string nodeName) const
Aggregate implementations of the ns3::Ipv4, ns3::Ipv6, ns3::Udp, and ns3::Tcp classes onto the provid...
#define NS_LOG_UNCOND(msg)
Output the requested message unconditionaly.
virtual void StopApplication(void)
Application specific shutdown code.
Definition: fifth.cc:126
virtual void StartApplication(void)
Application specific startup code.
Definition: fifth.cc:116
tuple stack
Definition: first.py:34
MyApp()
Definition: fifth.cc:88
void SetChannelAttribute(std::string name, const AttributeValue &value)
Set an attribute value to be propagated to each Channel created by the helper.
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...
An identifier for simulation events.
Definition: event-id.h:53
Ptr< Node > Get(uint32_t i) const
Get the Ptr stored in this container at a given index.
static TypeId GetTypeId(void)
Register this type.
Definition: seventh.cc:111
Time Seconds(double value)
Construct a Time in the indicated unit.
Definition: nstime.h:993
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.
Time Now(void)
create an ns3::Time instance which contains the current simulation time.
Definition: simulator.cc:365
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
static const uint32_t packetSize
tuple address
Definition: first.py:37
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.
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:185
a unique identifier for an interface.
Definition: type-id.h:58
void ScheduleTx(void)
Definition: fifth.cc:154
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:914
std::ostream * GetStream(void)
Return a pointer to an ostream previously set in the wrapper.
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
uint32_t m_packetSize
Definition: fifth.cc:80