examples/tcp-large-transfer.cc
changeset 2255 ac534291636f
parent 2227 48e8a213a27b
child 2257 71a58e70c671
equal deleted inserted replaced
2254:81fc1ce2d7bd 2255:ac534291636f
       
     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.pcap-$n-$i" where n and i represent node and interface numbers respectively
       
    29 //  Usage (e.g.): ./waf --run tcp-large-transfer
       
    30 
       
    31 #include <ctype.h>
       
    32 #include <iostream>
       
    33 #include <fstream>
       
    34 #include <string>
       
    35 #include <cassert>
       
    36 
       
    37 #include "ns3/command-line.h"
       
    38 #include "ns3/default-value.h"
       
    39 #include "ns3/ptr.h"
       
    40 #include "ns3/random-variable.h"
       
    41 #include "ns3/log.h"
       
    42 
       
    43 #include "ns3/simulator.h"
       
    44 #include "ns3/nstime.h"
       
    45 #include "ns3/data-rate.h"
       
    46 
       
    47 #include "ns3/ascii-trace.h"
       
    48 #include "ns3/pcap-trace.h"
       
    49 #include "ns3/internet-node.h"
       
    50 #include "ns3/point-to-point-channel.h"
       
    51 #include "ns3/point-to-point-net-device.h"
       
    52 #include "ns3/ipv4-address.h"
       
    53 #include "ns3/inet-socket-address.h"
       
    54 #include "ns3/ipv4.h"
       
    55 #include "ns3/socket.h"
       
    56 #include "ns3/ipv4-route.h"
       
    57 #include "ns3/point-to-point-topology.h"
       
    58 #include "ns3/onoff-application.h"
       
    59 #include "ns3/packet-sink.h"
       
    60 #include "ns3/error-model.h"
       
    61 #include "ns3/node-list.h"
       
    62 
       
    63 #include "ns3/tcp.h"
       
    64 
       
    65 using namespace ns3;
       
    66 
       
    67 NS_LOG_COMPONENT_DEFINE ("TcpLargeTransfer");
       
    68 
       
    69 void 
       
    70 ApplicationTraceSink (const TraceContext &context, Ptr<const Packet> packet,
       
    71   const Address &addr)
       
    72 {
       
    73 // g_log is not declared in optimized builds
       
    74 // should convert this to use of some other flag than the logging system
       
    75 #ifdef NS3_LOG_ENABLE
       
    76   if (!g_log.IsNoneEnabled ()) {
       
    77     if (InetSocketAddress::IsMatchingType (addr) )
       
    78       {
       
    79       InetSocketAddress address = InetSocketAddress::ConvertFrom (addr);
       
    80         std::cout << "PacketSink received size " << 
       
    81         packet->GetSize () << " at time " << 
       
    82         Simulator::Now ().GetSeconds () << " from address: " << 
       
    83         address.GetIpv4 () << std::endl;
       
    84         char buf[2000]; 
       
    85         memcpy(buf, packet->PeekData (), packet->GetSize ());
       
    86         for (uint32_t i=0; i < packet->GetSize (); i++)
       
    87           {
       
    88             std::cout << buf[i];
       
    89             if (i && i % 60 == 0) 
       
    90               std::cout << std::endl; 
       
    91           }
       
    92         std::cout << std::endl << std::endl;
       
    93     }
       
    94   }
       
    95 #endif
       
    96 }
       
    97 
       
    98 void CloseConnection (Ptr<Socket> localSocket)
       
    99 {
       
   100   //localSocket->Close ();
       
   101 }
       
   102 
       
   103 void StartFlow(Ptr<Socket> localSocket, uint32_t nBytes, 
       
   104   uint16_t servPort)
       
   105 {
       
   106  // NS_LOG_LOGIC("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
       
   107   localSocket->Connect (InetSocketAddress ("10.1.2.2", servPort));//connect
       
   108   localSocket->SetConnectCallback (MakeCallback (&CloseConnection),
       
   109                                    Callback<void, Ptr<Socket> > (),
       
   110                                    Callback<void, Ptr<Socket> > ());
       
   111   //we want to close as soon as the connection is established
       
   112   //the tcp state machine and outgoing buffer will assure that
       
   113   //all of the data is delivered
       
   114 
       
   115   // Perform series of 1040 byte writes (this is a multiple of 26 since
       
   116   // we want to detect data splicing in the output stream)
       
   117   uint32_t writeSize = 1040;
       
   118   uint8_t data[writeSize];
       
   119   while (nBytes > 0) {
       
   120     uint32_t curSize= nBytes > writeSize ? writeSize : nBytes;
       
   121     for(uint32_t i = 0; i < curSize; ++i)
       
   122     {
       
   123       char m = toascii (97 + i % 26);
       
   124       data[i] = m;
       
   125     }
       
   126     localSocket->Send (data, curSize);
       
   127     nBytes -= curSize;
       
   128   }
       
   129 }
       
   130 
       
   131 int main (int argc, char *argv[])
       
   132 {
       
   133 
       
   134   // Users may find it convenient to turn on explicit debugging
       
   135   // for selected modules; the below lines suggest how to do this
       
   136 //  LogComponentEnable("TcpL4Protocol", LOG_LEVEL_ALL);
       
   137 //  LogComponentEnable("TcpSocket", LOG_LEVEL_ALL);
       
   138 //  LogComponentEnable("PacketSink", LOG_LEVEL_ALL);
       
   139   //LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_ALL);
       
   140 
       
   141   // Allow the user to override any of the defaults and the above
       
   142   // Bind()s at run-time, via command-line arguments
       
   143   CommandLine::Parse (argc, argv);
       
   144 
       
   145   // Here, we will explicitly create three nodes.  In more sophisticated
       
   146   // topologies, we could configure a node factory.
       
   147   Ptr<Node> n0 = Create<InternetNode> ();
       
   148   Ptr<Node> n1 = Create<InternetNode> (); 
       
   149   Ptr<Node> n2 = Create<InternetNode> ();
       
   150 
       
   151   // We create the channels first without any IP addressing information
       
   152   Ptr<PointToPointChannel> channel0 = 
       
   153     PointToPointTopology::AddPointToPointLink (
       
   154     n0, n1, DataRate(10000000), MilliSeconds(10));
       
   155   
       
   156   // Later, we add IP addresses.  
       
   157   PointToPointTopology::AddIpv4Addresses (
       
   158       channel0, n0, Ipv4Address("10.1.3.1"),
       
   159       n1, Ipv4Address("10.1.3.2"));
       
   160 
       
   161   Ptr<PointToPointChannel> channel1 = 
       
   162       PointToPointTopology::AddPointToPointLink (
       
   163       n1, n2, DataRate(10000000), MilliSeconds(10));
       
   164   
       
   165   PointToPointTopology::AddIpv4Addresses (
       
   166       channel1, n1, Ipv4Address("10.1.2.1"),
       
   167       n2, Ipv4Address("10.1.2.2"));
       
   168   
       
   169   // Finally, we add static routes.  These three steps (Channel and
       
   170   // NetDevice creation, IP Address assignment, and routing) are 
       
   171   // separated because there may be a need to postpone IP Address
       
   172   // assignment (emulation) or modify to use dynamic routing
       
   173   PointToPointTopology::AddIpv4Routes(n0, n1, channel0);
       
   174   PointToPointTopology::AddIpv4Routes(n1, n2, channel1);
       
   175   Ptr<Ipv4> ipv4;
       
   176   ipv4 = n0->QueryInterface<Ipv4> ();
       
   177   ipv4->SetDefaultRoute (Ipv4Address ("10.1.3.2"), 1);
       
   178   ipv4 = n2->QueryInterface<Ipv4> ();
       
   179   ipv4->SetDefaultRoute (Ipv4Address ("10.1.2.1"), 1);
       
   180 
       
   181 
       
   182   ///////////////////////////////////////////////////////////////////////////
       
   183   // Simulation 1
       
   184   // 
       
   185   // Send 2000000 bytes over a connection to server port 50000 at time 0
       
   186   // Should observe SYN exchange, a lot of data segments, and FIN exchange
       
   187   //
       
   188   ///////////////////////////////////////////////////////////////////////////
       
   189 
       
   190   int nBytes = 2000000;
       
   191   uint16_t servPort = 50000;
       
   192 
       
   193   Ptr<SocketFactory> socketFactory = 
       
   194     n0->QueryInterface<SocketFactory> ();
       
   195   Ptr<Socket> localSocket = socketFactory->CreateSocket ();
       
   196   localSocket->Bind ();
       
   197 
       
   198   // Create a packet sink to receive these packets
       
   199   Ptr<PacketSink> sink = Create<PacketSink> (
       
   200     n2,
       
   201     InetSocketAddress (Ipv4Address::GetAny (), servPort),
       
   202     "Tcp");
       
   203   sink->Start (Seconds (0.0));
       
   204   sink->Stop (Seconds (100.0));
       
   205 
       
   206   Simulator::Schedule(Seconds(0), &StartFlow, localSocket, nBytes,
       
   207     servPort);
       
   208 
       
   209   // Configure tracing of all enqueue, dequeue, and NetDevice receive events
       
   210   // Trace output will be sent to the simple-examples.tr file
       
   211   AsciiTrace asciitrace ("tcp-large-transfer.tr");
       
   212   asciitrace.TraceAllQueues ();
       
   213   asciitrace.TraceAllNetDeviceRx ();
       
   214 
       
   215   
       
   216   // Also configure some tcpdump traces; each interface will be traced
       
   217   // The output files will be named 
       
   218   // simple-examples.pcap-<nodeId>-<interfaceId>
       
   219   // and can be read by the "tcpdump -r" command (use "-tt" option to
       
   220   // display timestamps correctly)
       
   221   PcapTrace pcaptrace ("tcp-large-transfer.pcap");
       
   222   pcaptrace.TraceAllIp ();
       
   223 
       
   224   NodeList::Connect ("/nodes/*/applications/*/rx", MakeCallback (&ApplicationTraceSink));
       
   225 
       
   226   Simulator::StopAt (Seconds(1000));
       
   227   Simulator::Run ();
       
   228   Simulator::Destroy ();
       
   229 }