A Discrete-Event Network Simulator
API
fifth.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 ("FifthScriptExample");
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 
66  MyApp ();
67  virtual ~MyApp();
68 
69  void Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate);
70 
71 private:
72  virtual void StartApplication (void);
73  virtual void StopApplication (void);
74 
75  void ScheduleTx (void);
76  void SendPacket (void);
77 
80  uint32_t m_packetSize;
81  uint32_t m_nPackets;
84  bool m_running;
85  uint32_t m_packetsSent;
86 };
87 
89  : m_socket (0),
90  m_peer (),
91  m_packetSize (0),
92  m_nPackets (0),
93  m_dataRate (0),
94  m_sendEvent (),
95  m_running (false),
96  m_packetsSent (0)
97 {
98 }
99 
101 {
102  m_socket = 0;
103 }
104 
105 void
106 MyApp::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
107 {
108  m_socket = socket;
109  m_peer = address;
111  m_nPackets = nPackets;
112  m_dataRate = dataRate;
113 }
114 
115 void
117 {
118  m_running = true;
119  m_packetsSent = 0;
120  m_socket->Bind ();
122  SendPacket ();
123 }
124 
125 void
127 {
128  m_running = false;
129 
130  if (m_sendEvent.IsRunning ())
131  {
132  Simulator::Cancel (m_sendEvent);
133  }
134 
135  if (m_socket)
136  {
137  m_socket->Close ();
138  }
139 }
140 
141 void
143 {
144  Ptr<Packet> packet = Create<Packet> (m_packetSize);
145  m_socket->Send (packet);
146 
147  if (++m_packetsSent < m_nPackets)
148  {
149  ScheduleTx ();
150  }
151 }
152 
153 void
155 {
156  if (m_running)
157  {
158  Time tNext (Seconds (m_packetSize * 8 / static_cast<double> (m_dataRate.GetBitRate ())));
159  m_sendEvent = Simulator::Schedule (tNext, &MyApp::SendPacket, this);
160  }
161 }
162 
163 static void
164 CwndChange (uint32_t oldCwnd, uint32_t newCwnd)
165 {
166  NS_LOG_UNCOND (Simulator::Now ().GetSeconds () << "\t" << newCwnd);
167 }
168 
169 static void
171 {
172  NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
173 }
174 
175 int
176 main (int argc, char *argv[])
177 {
179  cmd.Parse (argc, argv);
180 
182  nodes.Create (2);
183 
185  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
186  pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
187 
189  devices = pointToPoint.Install (nodes);
190 
191  Ptr<RateErrorModel> em = CreateObject<RateErrorModel> ();
192  em->SetAttribute ("ErrorRate", DoubleValue (0.00001));
193  devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
194 
196  stack.Install (nodes);
197 
199  address.SetBase ("10.1.1.0", "255.255.255.252");
200  Ipv4InterfaceContainer interfaces = address.Assign (devices);
201 
202  uint16_t sinkPort = 8080;
203  Address sinkAddress (InetSocketAddress (interfaces.GetAddress (1), sinkPort));
204  PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
205  ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
206  sinkApps.Start (Seconds (0.));
207  sinkApps.Stop (Seconds (20.));
208 
209  Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
210  ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndChange));
211 
212  Ptr<MyApp> app = CreateObject<MyApp> ();
213  app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("1Mbps"));
214  nodes.Get (0)->AddApplication (app);
215  app->SetStartTime (Seconds (1.));
216  app->SetStopTime (Seconds (20.));
217 
218  devices.Get (1)->TraceConnectWithoutContext ("PhyRxDrop", MakeCallback (&RxDrop));
219 
220  Simulator::Stop (Seconds (20));
221  Simulator::Run ();
222  Simulator::Destroy ();
223 
224  return 0;
225 }
226 
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
void SetStopTime(Time stop)
Specify application stop time.
Definition: application.cc:75
Simulation virtual time values and global simulation resolution.
Definition: nstime.h:102
Ptr< Socket > m_socket
Definition: fifth.cc:78
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)
#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
Build a set of PointToPointNetDevice objects.
Address m_peer
Definition: fifth.cc:79
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
static void RxDrop(Ptr< const Packet > p)
Definition: fifth.cc:170
void Setup(Ptr< Socket > socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
Definition: fifth.cc:106
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
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1489
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.
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.
static void CwndChange(uint32_t oldCwnd, uint32_t newCwnd)
Definition: fifth.cc:164
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
void ScheduleTx(void)
Definition: fifth.cc:154
void SetStartTime(Time start)
Specify application start time.
Definition: application.cc:69
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