Я новичок в 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 ();
}