运行reno

// Network topology

//

// n0 ---------- n1 ---------- n2 ---------- n3

// 10 Mbps 1 Mbps 10 Mbps

// 1 ms 10 ms 1 ms

//

// - TCP flow from n0 to n3 using BulkSendApplication.

// - The following simulation output is stored in results/ in ns-3 top-level directory:

// - cwnd traces are stored in cwndTraces folder

// - queue length statistics are stored in queue-size.dat file

// - pcaps are stored in pcap folder

// - queueTraces folder contain the drop statistics at queue

// - queueStats.txt file contains the queue stats and config.txt file contains

// the simulation configuration.

// - The cwnd and queue length traces obtained from this example were tested against

// the respective traces obtained from Linux Reno by using ns-3 Direct Code Execution.

// See internet/doc/tcp.rst for more details.

#include <iostream>

#include <string>

#include <fstream>

#include <sys/stat.h>

#include "ns3/core-module.h"

#include "ns3/network-module.h"

#include "ns3/internet-module.h"

#include "ns3/point-to-point-module.h"

#include "ns3/applications-module.h"

#include "ns3/traffic-control-module.h"

using namespace ns3;

std::string dir = "results/";

Time stopTime = Seconds (20);

uint32_t segmentSize = 524;

// Function to check queue length of Router 1

void

CheckQueueSize (Ptr<QueueDisc> queue)

{

uint32_t qSize = queue->GetCurrentSize ().GetValue ();

// Check queue size every 1/100 of a second

Simulator::Schedule (Seconds (0.001), &CheckQueueSize, queue);

std::ofstream fPlotQueue (std::stringstream (dir + "queue-size.dat").str ().c_str (), std::ios::out | std::ios::app);

fPlotQueue << Simulator::Now ().GetSeconds () << " " << qSize << std::endl;

fPlotQueue.close ();

}

// Function to trace change in cwnd at n0

static void

CwndChange (uint32_t oldCwnd, uint32_t newCwnd)

{

std::ofstream fPlotQueue (dir + "cwndTraces/n0.dat", std::ios::out | std::ios::app);

fPlotQueue << Simulator::Now ().GetSeconds () << " " << newCwnd / segmentSize << std::endl;

fPlotQueue.close ();

}

// Function to calculate drops in a particular Queue

static void

DropAtQueue (Ptr<OutputStreamWrapper> stream, Ptr<const QueueDiscItem> item)

{

*stream->GetStream () << Simulator::Now ().GetSeconds () << " 1" << std::endl;

}

// Trace Function for cwnd

void

TraceCwnd (uint32_t node, uint32_t cwndWindow,

Callback <void, uint32_t, uint32_t> CwndTrace)

{

Config::ConnectWithoutContext ("/NodeList/" + std::to_string (node) + "/$ns3::TcpL4Protocol/SocketList/" + std::to_string (cwndWindow) + "/CongestionWindow", CwndTrace);

}

// Function to install BulkSend application

void InstallBulkSend (Ptr<Node> node, Ipv4Address address, uint16_t port, std::string socketFactory,

uint32_t nodeId, uint32_t cwndWindow,

Callback <void, uint32_t, uint32_t> CwndTrace)

{

BulkSendHelper source (socketFactory, InetSocketAddress (address, port));

source.SetAttribute ("MaxBytes", UintegerValue (0));

ApplicationContainer sourceApps = source.Install (node);

sourceApps.Start (Seconds (0.0));

Simulator::Schedule (Seconds (0.0) + Seconds (0.001), &TraceCwnd, nodeId, cwndWindow, CwndTrace);

sourceApps.Stop (stopTime);

}

// Function to install sink application

void InstallPacketSink (Ptr<Node> node, uint16_t port, std::string socketFactory)

{

PacketSinkHelper sink (socketFactory, InetSocketAddress (Ipv4Address::GetAny (), port));

ApplicationContainer sinkApps = sink.Install (node);

sinkApps.Start (Seconds (0.0));

sinkApps.Stop (stopTime);

}

int main (int argc, char *argv[])

{

uint32_t stream = 1;

std::string socketFactory = "ns3::TcpSocketFactory";

std::string tcpTypeId = "ns3::TcpLinuxReno";

std::string qdiscTypeId = "ns3::FifoQueueDisc";

bool isSack = true;

uint32_t delAckCount = 1;

std::string recovery = "ns3::TcpClassicRecovery";

// 启用日志组件,以便打印 INFO 级别的日志

//LogComponentEnable("TcpLargeTransfer", LOG_LEVEL_INFO);

CommandLine cmd;

cmd.AddValue ("tcpTypeId", "TCP variant to use (e.g., ns3::TcpNewReno, ns3::TcpLinuxReno, etc.)", tcpTypeId);

cmd.AddValue ("qdiscTypeId", "Queue disc for gateway (e.g., ns3::CoDelQueueDisc)", qdiscTypeId);

cmd.AddValue ("segmentSize", "TCP segment size (bytes)", segmentSize);

cmd.AddValue ("delAckCount", "Delayed ack count", delAckCount);

cmd.AddValue ("enableSack", "Flag to enable/disable sack in TCP", isSack);

cmd.AddValue ("stopTime", "Stop time for applications / simulation time will be stopTime", stopTime);

cmd.AddValue ("recovery", "Recovery algorithm type to use (e.g., ns3::TcpPrrRecovery", recovery);

cmd.Parse (argc, argv);

TypeId qdTid;

NS_ABORT_MSG_UNLESS (TypeId::LookupByNameFailSafe (qdiscTypeId, &qdTid), "TypeId " << qdiscTypeId << " not found");

// Set recovery algorithm and TCP variant

Config::SetDefault ("ns3::TcpL4Protocol::RecoveryType", TypeIdValue (TypeId::LookupByName (recovery)));

if (tcpTypeId.compare ("ns3::TcpWestwoodPlus") == 0)

{

// TcpWestwoodPlus is not an actual TypeId name; we need TcpWestwood here

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));

// the default protocol type in ns3::TcpWestwood is WESTWOOD

Config::SetDefault ("ns3::TcpWestwood::ProtocolType", EnumValue (TcpWestwood::WESTWOODPLUS));

}

else

{

TypeId tcpTid;

NS_ABORT_MSG_UNLESS (TypeId::LookupByNameFailSafe (tcpTypeId, &tcpTid), "TypeId " << tcpTypeId << " not found");

Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TypeId::LookupByName (tcpTypeId)));

}

// Create nodes

NodeContainer leftNodes, rightNodes, routers;

routers.Create (2);

leftNodes.Create (1);

rightNodes.Create (1);

std::vector <NetDeviceContainer> leftToRouter;

std::vector <NetDeviceContainer> routerToRight;

// Create the point-to-point link helpers and connect two router nodes

PointToPointHelper pointToPointRouter;

pointToPointRouter.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));

pointToPointRouter.SetChannelAttribute ("Delay", StringValue ("150ms"));


 

NetDeviceContainer r1r2ND = pointToPointRouter.Install (routers.Get (0), routers.Get (1));

// Create the point-to-point link helpers and connect leaf nodes to router

PointToPointHelper pointToPointLeaf;

pointToPointLeaf.SetDeviceAttribute ("DataRate", StringValue ("1Mbps"));

pointToPointLeaf.SetChannelAttribute ("Delay", StringValue ("150ms"));

leftToRouter.push_back (pointToPointLeaf.Install (leftNodes.Get (0), routers.Get (0)));

routerToRight.push_back (pointToPointLeaf.Install (routers.Get (1), rightNodes.Get (0)));

InternetStackHelper internetStack;

internetStack.Install (leftNodes);

internetStack.Install (rightNodes);

internetStack.Install (routers);

// Assign IP addresses to all the network devices

Ipv4AddressHelper ipAddresses ("10.0.0.0", "255.255.255.0");

Ipv4InterfaceContainer r1r2IPAddress = ipAddresses.Assign (r1r2ND);

ipAddresses.NewNetwork ();

std::vector <Ipv4InterfaceContainer> leftToRouterIPAddress;

leftToRouterIPAddress.push_back (ipAddresses.Assign (leftToRouter [0]));

ipAddresses.NewNetwork ();

std::vector <Ipv4InterfaceContainer> routerToRightIPAddress;

routerToRightIPAddress.push_back (ipAddresses.Assign (routerToRight [0]));

Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

// Set default sender and receiver buffer size as 1MB

Config::SetDefault ("ns3::TcpSocket::SndBufSize", UintegerValue (1 << 20));

Config::SetDefault ("ns3::TcpSocket::RcvBufSize", UintegerValue (1 << 20));

// Set default initial congestion window as 10 segments

Config::SetDefault ("ns3::TcpSocket::InitialCwnd", UintegerValue (10));

// Set default delayed ack count to a specified value

Config::SetDefault ("ns3::TcpSocket::DelAckCount", UintegerValue (delAckCount));

// Set default segment size of TCP packet to a specified value

Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (segmentSize));

// Enable/Disable SACK in TCP

Config::SetDefault ("ns3::TcpSocketBase::Sack", BooleanValue (isSack));

// Create directories to store dat files

struct stat buffer;

[[maybe_unused]] int retVal;

if ((stat (dir.c_str (), &buffer)) == 0)

{

std::string dirToRemove = "rm -rf " + dir;

retVal = system (dirToRemove.c_str ());

NS_ASSERT_MSG (retVal == 0, "Error in return value");

}

std::string dirToSave = "mkdir -p " + dir;

retVal = system (dirToSave.c_str ());

NS_ASSERT_MSG (retVal == 0, "Error in return value");

retVal = system ((dirToSave + "/pcap/").c_str ());

NS_ASSERT_MSG (retVal == 0, "Error in return value");

retVal = system ((dirToSave + "/queueTraces/").c_str ());

NS_ASSERT_MSG (retVal == 0, "Error in return value");

retVal = system ((dirToSave + "/cwndTraces/").c_str ());

NS_ASSERT_MSG (retVal == 0, "Error in return value");

// Set default parameters for queue discipline

Config::SetDefault (qdiscTypeId + "::MaxSize", QueueSizeValue (QueueSize ("100p")));

// Install queue discipline on router

TrafficControlHelper tch;

tch.SetRootQueueDisc (qdiscTypeId);

QueueDiscContainer qd;

tch.Uninstall (routers.Get (0)->GetDevice (0));

qd.Add (tch.Install (routers.Get (0)->GetDevice (0)).Get (0));

// Enable BQL

tch.SetQueueLimits ("ns3::DynamicQueueLimits");

// Calls function to check queue size

Simulator::ScheduleNow (&CheckQueueSize, qd.Get (0));

AsciiTraceHelper asciiTraceHelper;

Ptr<OutputStreamWrapper> streamWrapper;

// Create dat to store packets dropped and marked at the router

streamWrapper = asciiTraceHelper.CreateFileStream (dir + "/queueTraces/drop-0.dat");

qd.Get (0)->TraceConnectWithoutContext ("Drop", MakeBoundCallback (&DropAtQueue, streamWrapper));

// Install packet sink at receiver side

uint16_t port = 50000;

InstallPacketSink (rightNodes.Get (0), port, "ns3::TcpSocketFactory");

// Install BulkSend application

InstallBulkSend (leftNodes.Get (0), routerToRightIPAddress [0].GetAddress (1), port, socketFactory, 2, 0, MakeCallback (&CwndChange));

// Enable PCAP on all the point to point interfaces

pointToPointLeaf.EnablePcapAll (dir + "pcap/ns-3", true);

Simulator::Stop (stopTime);

// 打印模拟开始前的当前模拟时间

//NS_LOG_INFO ("Simulator start at " << Simulator::Now ().GetSeconds () << " seconds");

Simulator::Run ();

// 打印模拟运行期间的某个时间点(例如,模拟开始后100秒)

//NS_LOG_INFO ("Simulator running at " << Simulator::Now ().GetSeconds () << " seconds");

// Store queue stats in a file

std::ofstream myfile;

myfile.open (dir + "queueStats.txt", std::fstream::in | std::fstream::out | std::fstream::app);

myfile << std::endl;

myfile << "Stat for Queue 1";

myfile << qd.Get (0)->GetStats ();

myfile.close ();

// Store configuration of the simulation in a file

myfile.open (dir + "config.txt", std::fstream::in | std::fstream::out | std::fstream::app);

myfile << "qdiscTypeId " << qdiscTypeId << "\n";

myfile << "stream " << stream << "\n";

myfile << "segmentSize " << segmentSize << "\n";

myfile << "delAckCount " << delAckCount << "\n";

myfile << "stopTime " << stopTime.As (Time::S) << "\n";

myfile.close ();

Simulator::Destroy ();

return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_48978047

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值