examples/tutorial/fifth.cc
changeset 5432 2cb21147d154
child 5433 be5517a35ea0
equal deleted inserted replaced
5431:01a657b8d1ef 5432:2cb21147d154
       
     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/common-module.h"
       
    20 #include "ns3/simulator-module.h"
       
    21 #include "ns3/node-module.h"
       
    22 #include "ns3/helper-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 SimpleSource : public Application 
       
    63 {
       
    64 public:
       
    65 
       
    66   SimpleSource ();
       
    67   virtual ~SimpleSource();
       
    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 
       
    78   Ptr<Socket>     m_socket;
       
    79   Address         m_peer;
       
    80   uint32_t        m_packetSize;
       
    81   uint32_t        m_nPackets;
       
    82   DataRate        m_dataRate;
       
    83   EventId         m_sendEvent;
       
    84   bool            m_running;
       
    85   uint32_t        m_packetsSent;
       
    86 };
       
    87 
       
    88 SimpleSource::SimpleSource ()
       
    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 
       
   100 SimpleSource::~SimpleSource()
       
   101 {
       
   102   m_socket = 0;
       
   103 }
       
   104 
       
   105 void
       
   106 SimpleSource::Setup (Ptr<Socket> socket, Address address, uint32_t packetSize, uint32_t nPackets, DataRate dataRate)
       
   107 {
       
   108   m_socket = socket;
       
   109   m_peer = address;
       
   110   m_packetSize = packetSize;
       
   111   m_nPackets = nPackets;
       
   112   m_dataRate = dataRate;
       
   113 }
       
   114 
       
   115 void
       
   116 SimpleSource::StartApplication (void)
       
   117 {
       
   118   m_running = true;
       
   119   m_packetsSent = 0;
       
   120   m_socket->Bind ();
       
   121   m_socket->Connect (m_peer);
       
   122   SendPacket ();
       
   123 }
       
   124 
       
   125 void 
       
   126 SimpleSource::StopApplication (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 
       
   142 SimpleSource::SendPacket (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 
       
   154 SimpleSource::ScheduleTx (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, &SimpleSource::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
       
   170 RxDrop (Ptr<const Packet> p)
       
   171 {
       
   172   NS_LOG_UNCOND ("RxDrop at " << Simulator::Now ().GetSeconds ());
       
   173 }
       
   174 
       
   175 int 
       
   176 main (int argc, char *argv[])
       
   177 {
       
   178   NodeContainer nodes;
       
   179   nodes.Create (2);
       
   180 
       
   181   PointToPointHelper pointToPoint;
       
   182   pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));
       
   183   pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
       
   184 
       
   185   NetDeviceContainer devices;
       
   186   devices = pointToPoint.Install (nodes);
       
   187 
       
   188   Ptr<RateErrorModel> em = CreateObjectWithAttributes<RateErrorModel> (
       
   189     "RanVar", RandomVariableValue (UniformVariable (0., 1.)),
       
   190     "ErrorRate", DoubleValue (0.00001));
       
   191   devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
       
   192 
       
   193   InternetStackHelper stack;
       
   194   stack.Install (nodes);
       
   195 
       
   196   Ipv4AddressHelper address;
       
   197   address.SetBase ("10.1.1.0", "255.255.255.252");
       
   198   Ipv4InterfaceContainer interfaces = address.Assign (devices);
       
   199 
       
   200   uint16_t sinkPort = 8080;
       
   201   Address sinkAddress (InetSocketAddress(interfaces.GetAddress (1), sinkPort));
       
   202   PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), sinkPort));
       
   203   ApplicationContainer sinkApps = packetSinkHelper.Install (nodes.Get (1));
       
   204   sinkApps.Start (Seconds (0.));
       
   205   sinkApps.Stop (Seconds (20.));
       
   206 
       
   207   Ptr<Socket> ns3TcpSocket = Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
       
   208   ns3TcpSocket->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndChange));
       
   209 
       
   210   Ptr<SimpleSource> app = CreateObject<SimpleSource> ();
       
   211   app->Setup (ns3TcpSocket, sinkAddress, 1040, 1000, DataRate ("5Mbps"));
       
   212   nodes.Get (0)->AddApplication (app);
       
   213   app->Start (Seconds (1.));
       
   214   app->Stop (Seconds (20.));
       
   215 
       
   216   devices.Get (1)->TraceConnectWithoutContext("PhyRxDrop", MakeCallback (&RxDrop));
       
   217 
       
   218   Simulator::Stop (Seconds(20));
       
   219   Simulator::Run ();
       
   220   Simulator::Destroy ();
       
   221 
       
   222   return 0;
       
   223 }
       
   224