Как изменить полезную нагрузку TCP в NS3? - PullRequest
0 голосов
/ 29 мая 2018

Я новичок в ns3 и внедряю код, чтобы проверить, как различные MTU влияют на пропускную способность.Однако полезная нагрузка ограничена 536 байтами, что делает все мои MTU одинаковыми по времени.Как мне изменить его?

Я пытался редактировать переменную writeize, равную MTU, но полезная нагрузка ограничивает то, чего я пытаюсь достичь.

Мой код:

#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 ();
}
...