如何在NS3中更改TCP有效负载?

时间:2018-05-29 02:26:45

标签: ns-3

我是ns3的新手,我正在实施一个代码来测试不同的MTU如何影响吞吐量。然而,有效载荷似乎被限制在536字节,这使得我的所有MTU具有相似的时序。我该如何改变呢?

我尝试编辑等于MTU的变量writesize,但有效负载限制了我试图实现的目标。

我的代码:

#include <iostream>
#include <fstream>
#include <string>
#include "ns3/netanim-module.h"
#include "ns3/core-module.h"
#include "ns3/applications-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/ipv4-global-routing-helper.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("TCPtest");

// The number of bytes to send in this simulation.
static const uint32_t totalTxBytes = 30000000;
static uint32_t currentTxBytes = 0;
// Perform series of 1040 byte writes (this is a multiple of 26 since
// we want to detect data splicing in the output stream)
static const uint32_t writeSize = 9000;
uint8_t data[writeSize];

// These are for starting the writing process, and handling the sending
// socket's notification upcalls (events).  These two together more or less
// implement a sending "Application", although not a proper ns3::Application
// subclass.

void StartFlow (Ptr<Socket>, Ipv4Address, uint16_t);
void WriteUntilBufferFull (Ptr<Socket>, uint32_t);
static void
CwndTracer (uint32_t oldval, uint32_t newval)
{
  NS_LOG_INFO ("Moving cwnd from " << oldval << " to " << newval);
}

int
main (int argc, char *argv[])
{
    Time::SetResolution (Time::NS);


// initialize the tx buffer.
    for(uint32_t i = 0; i < writeSize; ++i)
    {
    char m = toascii (97 + i % 26);
    data[i] = m;
    }


    NodeContainer nodes;
    nodes.Create (6);
    StringValue Mtu;
    Mtu.Set("9000");
    InternetStackHelper stack;
    stack.Install (nodes);

    PointToPointHelper p2p1;
    p2p1.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
    p2p1.SetChannelAttribute ("Delay", StringValue ("5ms"));
    p2p1.SetDeviceAttribute ("Mtu", Mtu);

    PointToPointHelper p2p2;
    p2p2.SetDeviceAttribute ("DataRate", StringValue ("1Gbps"));
    p2p2.SetChannelAttribute ("Delay", StringValue ("300ms"));
    p2p2.SetDeviceAttribute ("Mtu", StringValue ("9000"));

    PointToPointHelper p2p3;
    p2p3.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
    p2p3.SetChannelAttribute ("Delay", StringValue ("5ms"));
    p2p3.SetDeviceAttribute ("Mtu", StringValue ("9000"));

    Ipv4AddressHelper address;
    address.SetBase ("10.1.1.0", "255.255.255.0");
    NetDeviceContainer devices;
    devices = p2p1.Install (nodes.Get (0), nodes.Get (1));
    Ipv4InterfaceContainer interfaces = address.Assign (devices);
    address.SetBase ("10.1.4.0", "255.255.255.0");
    devices = p2p1.Install (nodes.Get (4), nodes.Get (1));
    interfaces = address.Assign (devices);


    devices = p2p2.Install (nodes.Get (1), nodes.Get (2));
    address.SetBase ("10.1.2.0", "255.255.255.0");
    interfaces = address.Assign (devices);

    devices = p2p3.Install (nodes.Get (2), nodes.Get (3));
    address.SetBase ("10.1.3.0", "255.255.255.0");
    interfaces = address.Assign (devices);
    devices = p2p3.Install (nodes.Get (2), nodes.Get (5));
    address.SetBase ("10.1.5.0", "255.255.255.0");
    Ipv4InterfaceContainer interfaces2 = address.Assign (devices);

    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

    uint16_t port = 9;

      // Create a packet sink to receive these packets on n1...
    PacketSinkHelper sink ("ns3::TcpSocketFactory",
                        InetSocketAddress (Ipv4Address::GetAny (), port));

    ApplicationContainer apps = sink.Install (nodes.Get (3));
    apps.Start (Seconds (0.0));
    apps.Stop (Seconds (10.0));
    PacketSinkHelper sink2 ("ns3::TcpSocketFactory",
                        InetSocketAddress (Ipv4Address::GetAny (), port));

    ApplicationContainer apps2 = sink2.Install (nodes.Get (5));
    apps2.Start (Seconds (0.0));
    apps2.Stop (Seconds (10.0));


  // Create and bind the socket...
    Ptr<Socket> localSocket =
    Socket::CreateSocket (nodes.Get (0), TcpSocketFactory::GetTypeId ());
    localSocket->Bind ();
    Ptr<Socket> localSocket2 =
    Socket::CreateSocket (nodes.Get (4), TcpSocketFactory::GetTypeId ());
    localSocket2->Bind ();

  // Trace changes to the congestion window
    Config::ConnectWithoutContext ("/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", MakeCallback (&CwndTracer));

  // ...and schedule the sending "Application"; This is similar to what an
  // ns3::Application subclass would do internally.
    Simulator::ScheduleNow (&StartFlow, localSocket, interfaces.GetAddress (1), port);
    Simulator::ScheduleNow (&StartFlow, localSocket2, interfaces2.GetAddress (1), port);
  // One can toggle the comment for the following line on or off to see the
  // effects of finite send buffer modelling.  One can also change the size of    
  // said buffer.

  //localSocket->SetAttribute("SndBufSize", UintegerValue(4096));

  //Ask for ASCII and pcap traces of network traffic
    AsciiTraceHelper ascii;
    p2p3.EnableAsciiAll (ascii.CreateFileStream ("tcp-test1.tr"));
    p2p3.EnablePcapAll ("tcp-test1");




    AnimationInterface anim ("tcptest.xml");
    anim.SetConstantPosition (nodes.Get (0), 0.0, 0.0);
    anim.SetConstantPosition (nodes.Get (1), 20.0, 25.0);
    anim.SetConstantPosition (nodes.Get (2), 35.0, 40.0);
    anim.SetConstantPosition (nodes.Get (3), 50.0, 55.0);

    Simulator::Run ();
    Simulator::Destroy ();

    return 0;
}

void StartFlow (Ptr<Socket> localSocket,
                Ipv4Address servAddress,
                uint16_t servPort)
{
  NS_LOG_LOGIC ("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
  localSocket->Connect (InetSocketAddress (servAddress, servPort)); //connect

  // tell the tcp implementation to call WriteUntilBufferFull again
  // if we blocked and new tx buffer space becomes available
  localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull));
  WriteUntilBufferFull (localSocket, localSocket->GetTxAvailable ());
}

void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t txSpace)
{
  while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0)
    {
    uint32_t left = totalTxBytes - currentTxBytes;
    uint32_t dataOffset = currentTxBytes % writeSize;
    uint32_t toWrite = writeSize - dataOffset;
    toWrite = std::min (toWrite, left);
    toWrite = std::min (toWrite, localSocket->GetTxAvailable ());
    int amountSent = localSocket->Send (&data[dataOffset], toWrite, 0);
    if(amountSent < 0)
        {
        // we will be called again when new tx space becomes available.
        return;
        }
    currentTxBytes += amountSent;
    }
  localSocket->Close ();
}

0 个答案:

没有答案