NS-3源文件中包含有许多样例和说明文档,大家可以参考学习。针对本实验室需要完成工作的一部分,也就是源节点向目的节点发送Tcp数据包,数据包大小满足均匀分布,发包过程满足泊松分布(即发包间隔满足指数分布)的要求,没有现成的样例可以借鉴,思考之后,决定修改onoffapplication和OnOffHelper相关源码。
OnOffApplication类声明和实现中,PacketSize是一个常数,
.AddAttribute ("PacketSize", "The size of packets sent in on state",
UintegerValue (512),
MakeUintegerAccessor (&OnOffApplication::m_pktSize),
MakeUintegerChecker<uint32_t> (1))
一旦设定,本次仿真无法更改;
而且也没有发包间隔Interval这一属性。
为不影响系统其他模块的使用,将涉及到onoffapplication类定义和声明的头文件,源文件全部拷贝进入一个.cc文件。包括onoff-application.h;onoff-application.cc;on-off helper.h;onoff helper.cc
相关类名之前加上前缀,如my,即类名分别为myOnOffApplication,myOnOffHelper。
新增变量:
Ptr<RandomVariableStream> m_interval;
Ptr<RandomVariableStream> m__packetsize;
myOnOffApplication类实现中,增加语句
.AddAttribute ("PacketSize", "The size of packets sent in on state",
StringValue ("ns3::ConstantRandomVariable[Constant=137]"),
MakePointerAccessor (&myOnOffApplication::m__packetsize),
MakePointerChecker <RandomVariableStream>())
.AddAttribute ("Interval", "The time between packets sent in on state",
StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
MakePointerAccessor (&myOnOffApplication::m_interval),
MakePointerChecker <RandomVariableStream>())
在成员函数myOnOffApplication::AssignStreams (int64_t stream)中添加语句
m_interval->SetStream (stream + 2);
m__packetsize->SetStream (stream + 3);
return 4;
在成员函数myOnOffApplication::ScheduleNextTx ()中添加语句
m_pktSize=m__packetsize->GetValue();
来控制数据包大小;
添加语句
double myinterval=m_interval->GetValue();
cout << "the interval is "<<myinterval<<endl;
Time nextTime (Seconds (bits /
static_cast<double>(m_cbrRate.GetBitRate ())+myinterval));
NS_LOG_LOGIC ("nextTime = " << nextTime);
之后只需修改OnOffHelper类名为myOnOffHelper即可。
关键是数据PacketSize和Interval格式的改变,将两者都定义为随机变量流。
统计数据包大小和发包间隔,利用Gnuplot画图如下
数据包大小在100-137字节之间均匀分布;
发包间隔为指数分布。
希望对大家的学习有所帮助!
可直接运行的源码如下:
#include <fstream>
#include "ns3/gnuplot.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/random-variable-stream.h"
#include "ns3/rng-seed-manager.h"
#include <iostream>
#include "ns3/gnuplot.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/netanim-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-layout-module.h"
#include "ns3/netanim-module.h"
#include "ns3/address.h"
#include "ns3/application.h"
#include "ns3/event-id.h"
#include "ns3/ptr.h"
#include "ns3/data-rate.h"
#include "ns3/traced-callback.h"
#include "ns3/log.h"
#include "ns3/address.h"
#include "ns3/inet-socket-address.h"
#include "ns3/inet6-socket-address.h"
#include "ns3/packet-socket-address.h"
#include "ns3/node.h"
#include "ns3/nstime.h"
#include "ns3/data-rate.h"
#include "ns3/random-variable-stream.h"
#include "ns3/socket.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/packet.h"
#include "ns3/uinteger.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/onoff-application.h"
#include "ns3/udp-socket-factory.h"
#include "ns3/string.h"
#include "ns3/pointer.h"
#include "ns3/on-off-helper.h"
#include "ns3/inet-socket-address.h"
#include "ns3/packet-socket-address.h"
#include "ns3/string.h"
#include "ns3/data-rate.h"
#include "ns3/uinteger.h"
#include "ns3/names.h"
#include "ns3/random-variable-stream.h"
#include <stdint.h>
#include <string>
#include "ns3/object-factory.h"
#include "ns3/address.h"
#include "ns3/attribute.h"
#include "ns3/net-device.h"
#include "ns3/node-container.h"
#include "ns3/application-container.h"
#include "ns3/onoff-application.h"
#include <fstream>
#include "ns3/gnuplot.h"
#include "algorithm"
using namespace std;
using namespace ns3;
///统计画图模块/
// Gnuplot2dDataset dataset_interval2;
std::string fileNameWithNoExtension = "uniform";
std::string graphicsFileName = fileNameWithNoExtension + ".png";
std::string plotFileName = fileNameWithNoExtension + ".plt";
std::string plotTitle = "packetsizes interval";
std::string dataTitle = "uniform-D Data";
// Instantiate the plot and set its title.
Gnuplot plot (graphicsFileName);
Gnuplot2dDataset dataset_interval;
/
std::string fileNameWithNoExtension2 = "packetsize";
std::string graphicsFileName2 = fileNameWithNoExtension2 + ".png";
std::string plotFileName2 = fileNameWithNoExtension2 + ".plt";
std::string plotTitle2 = "packetsizes ";
std::string dataTitle2 = "uniform-D Data";
// Instantiate the plot and set its title.
Gnuplot plot2 (graphicsFileName2);
Gnuplot2dDataset dataset_packetsize;
//dataset_interval.SetTitle (dataTitle);
//dataset_interval.SetStyle (Gnuplot2dDataset::LINES_POINTS);
int count_packets=0;
double data_interval[48];
int data_packetsize[48];
// onoff-application .h 类声明
namespace ns3 {
class Address;
class RandomVariableStream;
class Socket;
class myOnOffApplication : public Application
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId (void);
myOnOffApplication ();
virtual ~myOnOffApplication();
/**
* \brief Set the total number of bytes to send.
*
* Once these bytes are sent, no packet is sent again, even in on state.
* The value zero means that there is no limit.
*
* \param maxBytes the total number of bytes to send
*/
void SetMaxBytes (uint32_t maxBytes);
/**
* \brief Return a pointer to associated socket.
* \return pointer to associated socket
*/
Ptr<Socket> GetSocket (void) const;
/**
* \brief Assign a fixed random variable stream number to the random variables
* used by this model.
*
* \param stream first stream index to use
* \return the number of stream indices assigned by this model
*/
int64_t AssignStreams (int64_t stream);
protected:
virtual void DoDispose (void);
private:
// inherited from Application base class.
virtual void StartApplication (void); // Called at time specified by Start
virtual void StopApplication (void); // Called at time specified by Stop
//helpers
/**
* \brief Cancel all pending events.
*/
void CancelEvents ();
void StartSending ();
/**
* \brief Start an Off period
*/
void StopSending ();
void SendPacket ();
Ptr<Socket> m_socket; //!< Associated socket
Address m_peer; //!< Peer address
bool m_connected; //!< True if connected
Ptr<RandomVariableStream> m_onTime; //!< rng for On Time
Ptr<RandomVariableStream> m_offTime; //!< rng for Off Time
Ptr<RandomVariableStream> m_interval;
Ptr<RandomVariableStream> m__packetsize;
DataRate m_cbrRate; //!< Rate that data is generated
DataRate m_cbrRateFailSafe; //!< Rate that data is generated (check copy)
uint32_t m_pktSize; //!< Size of packets
uint32_t m_residualBits; //!< Number of generated, but not sent, bits
Time m_lastStartTime; //!< Time last packet sent
uint32_t m_maxBytes; //!< Limit total number of bytes sent
uint32_t m_totBytes; //!< Total bytes sent so far
EventId m_startStopEvent; //!< Event id for next start or stop event
EventId m_sendEvent; //!< Event id of pending "send packet" event
TypeId m_tid; //!< Type of the socket used
// int count_packets;
/// Traced Callback: transmitted packets.
TracedCallback<Ptr<const Packet> > m_txTrace;
private:
/**
* \brief Schedule the next packet transmission
*/
void ScheduleNextTx ();
/**
* \brief Schedule the next On period start
*/
void ScheduleStartEvent ();
/**
* \brief Schedule the next Off period start
*/
void ScheduleStopEvent ();
void ConnectionSucceeded (Ptr<Socket> socket);
/**
* \brief Handle a Connection Failed event
* \param socket the not connected socket
*/
void ConnectionFailed (Ptr<Socket> socket);
};
} // namespace ns3
///
///onoff-application.cc 类的实现
namespace ns3 {
NS_LOG_COMPONENT_DEFINE ("myOnOffApplication");
NS_OBJECT_ENSURE_REGISTERED (myOnOffApplication);
TypeId
myOnOffApplication::GetTypeId (void)
{
static TypeId tid = TypeId ("ns3::myOnOffApplication")
.SetParent<Application> ()
.SetGroupName("Applications")
.AddConstructor<myOnOffApplication> ()
.AddAttribute ("DataRate", "The data rate in on state.",
DataRateValue (DataRate ("500kb/s")),
MakeDataRateAccessor (&myOnOffApplication::m_cbrRate),
MakeDataRateChecker ())
.AddAttribute ("PacketSize", "The size of packets sent in on state",
StringValue ("ns3::ConstantRandomVariable[Constant=137]"),
MakePointerAccessor (&myOnOffApplication::m__packetsize),
MakePointerChecker <RandomVariableStream>())
.AddAttribute ("Interval", "The time between packets sent in on state",
StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
MakePointerAccessor (&myOnOffApplication::m_interval),
MakePointerChecker <RandomVariableStream>())
.AddAttribute ("Remote", "The address of the destination",
AddressValue (),
MakeAddressAccessor (&myOnOffApplication::m_peer),
MakeAddressChecker ())
.AddAttribute ("OnTime", "A RandomVariableStream used to pick the duration of the 'On' state.",
StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
MakePointerAccessor (&myOnOffApplication::m_onTime),
MakePointerChecker <RandomVariableStream>())
.AddAttribute ("OffTime", "A RandomVariableStream used to pick the duration of the 'Off' state.",
StringValue ("ns3::ConstantRandomVariable[Constant=1.0]"),
MakePointerAccessor (&myOnOffApplication::m_offTime),
MakePointerChecker <RandomVariableStream>())
.AddAttribute ("MaxBytes",
"The total number of bytes to send. Once these bytes are sent, "
"no packet is sent again, even in on state. The value zero means "
"that there is no limit.",
UintegerValue (0),
MakeUintegerAccessor (&myOnOffApplication::m_maxBytes),
MakeUintegerChecker<uint32_t> ())
.AddAttribute ("Protocol", "The type of protocol to use.",
TypeIdValue (UdpSocketFactory::GetTypeId ()),
MakeTypeIdAccessor (&myOnOffApplication::m_tid),
MakeTypeIdChecker ())
.AddTraceSource ("Tx", "A new packet is created and is sent",
MakeTraceSourceAccessor (&myOnOffApplication::m_txTrace),
"ns3::Packet::TracedCallback")
;
return tid;
}
myOnOffApplication::myOnOffApplication ()
: m_socket (0),
m_connected (false),
m_residualBits (0),
m_lastStartTime (Seconds (0)),
// count_packets(0),
m_totBytes (0)
{
NS_LOG_FUNCTION (this);
}
myOnOffApplication::~myOnOffApplication()
{
NS_LOG_FUNCTION (this);
}
void
myOnOffApplication::SetMaxBytes (uint32_t maxBytes)
{
NS_LOG_FUNCTION (this << maxBytes);
m_maxBytes = maxBytes;
}
Ptr<Socket>
myOnOffApplication::GetSocket (void) const
{
NS_LOG_FUNCTION (this);
return m_socket;
}
int64_t
myOnOffApplication::AssignStreams (int64_t stream)
{
NS_LOG_FUNCTION (this << stream);
m_onTime->SetStream (stream);
m_offTime->SetStream (stream + 1);
m_interval->SetStream (stream + 2);
m__packetsize->SetStream (stream + 3);
return 4;
}
void
myOnOffApplication::DoDispose (void)
{
NS_LOG_FUNCTION (this);
m_socket = 0;
// chain up
Application::DoDispose ();
}
// Application Methods
void myOnOffApplication::StartApplication () // Called at time specified by Start
{
NS_LOG_FUNCTION (this);
// Create the socket if not already
if (!m_socket)
{
m_socket = Socket::CreateSocket (GetNode (), m_tid);
if (Inet6SocketAddress::IsMatchingType (m_peer))
{
m_socket->Bind6 ();
}
else if (InetSocketAddress::IsMatchingType (m_peer) ||
PacketSocketAddress::IsMatchingType (m_peer))
{
m_socket->Bind ();
}
m_socket->Connect (m_peer);
m_socket->SetAllowBroadcast (true);
m_socket->ShutdownRecv ();
m_socket->SetConnectCallback (
MakeCallback (&myOnOffApplication::ConnectionSucceeded, this),
MakeCallback (&myOnOffApplication::ConnectionFailed, this));
}
m_cbrRateFailSafe = m_cbrRate;
// Insure no pending event
CancelEvents ();
// If we are not yet connected, there is nothing to do here
// The ConnectionComplete upcall will start timers at that time
//if (!m_connected) return;
ScheduleStartEvent ();
}
void myOnOffApplication::StopApplication () // Called at time specified by Stop
{
NS_LOG_FUNCTION (this);
CancelEvents ();
if(m_socket != 0)
{
m_socket->Close ();
}
else
{
NS_LOG_WARN ("myOnOffApplication found null socket to close in StopApplication");
}
}
void myOnOffApplication::CancelEvents ()
{
NS_LOG_FUNCTION (this);
if (m_sendEvent.IsRunning () && m_cbrRateFailSafe == m_cbrRate )
{ // Cancel the pending send packet event
// Calculate residual bits since last packet sent
Time delta (Simulator::Now () - m_lastStartTime);
int64x64_t bits = delta.To (Time::S) * m_cbrRate.GetBitRate ();
m_residualBits += bits.GetHigh ();
}
m_cbrRateFailSafe = m_cbrRate;
Simulator::Cancel (m_sendEvent);
Simulator::Cancel (m_startStopEvent);
}
// Event handlers
void myOnOffApplication::StartSending ()
{
NS_LOG_FUNCTION (this);
m_lastStartTime = Simulator::Now ();
ScheduleNextTx (); // Schedule the send packet event
ScheduleStopEvent ();
}
void myOnOffApplication::StopSending ()
{
NS_LOG_FUNCTION (this);
CancelEvents ();
ScheduleStartEvent ();
}
void myOnOffApplication::ScheduleNextTx ()
{
NS_LOG_FUNCTION (this);
if (m_maxBytes == 0 || m_totBytes < m_maxBytes)
{
cout<<"第几次进入 ScheduleNextTx ()"<<endl;
m_pktSize=m__packetsize->GetValue(); // 添加这一个数据包大小控制语句
data_packetsize[count_packets]=m_pktSize;
uint32_t bits = m_pktSize * 8 - m_residualBits;
NS_LOG_LOGIC ("bits = " << bits);
double myinterval=m_interval->GetValue();
cout << "the interval is "<<myinterval<<endl;
data_interval[count_packets]=myinterval;
count_packets++;
// dataset_interval.Add(count_packets,myinterval);
Time nextTime (Seconds (bits /
static_cast<double>(m_cbrRate.GetBitRate ())+myinterval)); // Time till next packet
NS_LOG_LOGIC ("nextTime = " << nextTime);
m_sendEvent = Simulator::Schedule (nextTime,
&myOnOffApplication::SendPacket, this);
}
else
{ // All done, cancel any pending events
StopApplication ();
}
}
void myOnOffApplication::ScheduleStartEvent ()
{ // Schedules the event to start sending data (switch to the "On" state)
NS_LOG_FUNCTION (this);
Time offInterval = Seconds (m_offTime->GetValue ());
NS_LOG_LOGIC ("start at " << offInterval);
m_startStopEvent = Simulator::Schedule (offInterval, &myOnOffApplication::StartSending, this);
}
void myOnOffApplication::ScheduleStopEvent ()
{ // Schedules the event to stop sending data (switch to "Off" state)
NS_LOG_FUNCTION (this);
Time onInterval = Seconds (m_onTime->GetValue ());
NS_LOG_LOGIC ("stop at " << onInterval);
m_startStopEvent = Simulator::Schedule (onInterval, &myOnOffApplication::StopSending, this);
}
void myOnOffApplication::SendPacket ()
{
NS_LOG_FUNCTION (this);
NS_ASSERT (m_sendEvent.IsExpired ());
Ptr<Packet> packet = Create<Packet> (m_pktSize);
m_txTrace (packet);
m_socket->Send (packet);
m_totBytes += m_pktSize;
if (InetSocketAddress::IsMatchingType (m_peer))
{
NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds ()
<< "s on-off application sent "
<< packet->GetSize () << " bytes to "
<< InetSocketAddress::ConvertFrom(m_peer).GetIpv4 ()
<< " port " << InetSocketAddress::ConvertFrom (m_peer).GetPort ()
<< " total Tx " << m_totBytes << " bytes");
}
else if (Inet6SocketAddress::IsMatchingType (m_peer))
{
NS_LOG_INFO ("At time " << Simulator::Now ().GetSeconds ()
<< "s on-off application sent "
<< packet->GetSize () << " bytes to "
<< Inet6SocketAddress::ConvertFrom(m_peer).GetIpv6 ()
<< " port " << Inet6SocketAddress::ConvertFrom (m_peer).GetPort ()
<< " total Tx " << m_totBytes << " bytes");
}
m_lastStartTime = Simulator::Now ();
m_residualBits = 0;
ScheduleNextTx ();
}
void myOnOffApplication::ConnectionSucceeded (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket);
m_connected = true;
}
void myOnOffApplication::ConnectionFailed (Ptr<Socket> socket)
{
NS_LOG_FUNCTION (this << socket);
}
} // Namespace ns3
on-off helper .h 头文件
namespace ns3 {
class DataRate;
/**
* \ingroup onoff
* \brief A helper to make it easier to instantiate an ns3::myOnOffApplication
* on a set of nodes.
*/
class myOnOffHelper
{
public:
/**
* Create an myOnOffHelper to make it easier to work with myOnOffApplications
*
* \param protocol the name of the protocol to use to send traffic
* by the applications. This string identifies the socket
* factory type used to create sockets for the applications.
* A typical value would be ns3::UdpSocketFactory.
* \param address the address of the remote node to send traffic
* to.
*/
myOnOffHelper (std::string protocol, Address address);
/**
* Helper function used to set the underlying application attributes.
*
* \param name the name of the application attribute to set
* \param value the value of the application attribute to set
*/
void SetAttribute (std::string name, const AttributeValue &value);
/**
* Helper function to set a constant rate source. Equivalent to
* setting the attributes OnTime to constant 1000 seconds, OffTime to
* constant 0 seconds, and the DataRate and PacketSize set accordingly
*
* \param dataRate DataRate object for the sending rate
* \param packetSize size in bytes of the packet payloads generated
*/
void SetConstantRate (DataRate dataRate, uint32_t packetSize = 512);
/**
* Install an ns3::myOnOffApplication on each node of the input container
* configured with all the attributes set with SetAttribute.
*
* \param c NodeContainer of the set of nodes on which an myOnOffApplication
* will be installed.
* \returns Container of Ptr to the applications installed.
*/
ApplicationContainer Install (NodeContainer c) const;
ApplicationContainer Install (Ptr<Node> node) const;
/**
* Install an ns3::myOnOffApplication on the node configured with all the
* attributes set with SetAttribute.
*
* \param nodeName The node on which an myOnOffApplication will be installed.
* \returns Container of Ptr to the applications installed.
*/
ApplicationContainer Install (std::string nodeName) const;
/**
* Assign a fixed random variable stream number to the random variables
* used by this model. Return the number of streams (possibly zero) that
* have been assigned. The Install() method should have previously been
* called by the user.
*
* \param stream first stream index to use
* \param c NodeContainer of the set of nodes for which the myOnOffApplication
* should be modified to use a fixed stream
* \return the number of stream indices assigned by this helper
*/
int64_t AssignStreams (NodeContainer c, int64_t stream);
private:
/**
* Install an ns3::myOnOffApplication on the node configured with all the
* attributes set with SetAttribute.
*
* \param node The node on which an myOnOffApplication will be installed.
* \returns Ptr to the application installed.
*/
Ptr<Application> InstallPriv (Ptr<Node> node) const;
ObjectFactory m_factory; //!< Object factory.
};
} // namespace ns3
// onoff helper.cc 实现
namespace ns3 {
myOnOffHelper::myOnOffHelper (std::string protocol, Address address)
{
m_factory.SetTypeId ("ns3::myOnOffApplication");
m_factory.Set ("Protocol", StringValue (protocol));
m_factory.Set ("Remote", AddressValue (address));
}
void
myOnOffHelper::SetAttribute (std::string name, const AttributeValue &value)
{
m_factory.Set (name, value);
}
ApplicationContainer
myOnOffHelper::Install (Ptr<Node> node) const
{
return ApplicationContainer (InstallPriv (node));
}
ApplicationContainer
myOnOffHelper::Install (std::string nodeName) const
{
Ptr<Node> node = Names::Find<Node> (nodeName);
return ApplicationContainer (InstallPriv (node));
}
ApplicationContainer
myOnOffHelper::Install (NodeContainer c) const
{
ApplicationContainer apps;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
{
apps.Add (InstallPriv (*i));
}
return apps;
}
Ptr<Application>
myOnOffHelper::InstallPriv (Ptr<Node> node) const
{
Ptr<Application> app = m_factory.Create<Application> ();
node->AddApplication (app);
return app;
}
int64_t
myOnOffHelper::AssignStreams (NodeContainer c, int64_t stream)
{
int64_t currentStream = stream;
Ptr<Node> node;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
{
node = (*i);
for (uint32_t j = 0; j < node->GetNApplications (); j++)
{
Ptr<myOnOffApplication> onoff = DynamicCast<myOnOffApplication> (node->GetApplication (j));
if (onoff)
{
currentStream += onoff->AssignStreams (currentStream);
}
}
}
return (currentStream - stream);
}
void
myOnOffHelper::SetConstantRate (DataRate dataRate, uint32_t packetSize)
{
m_factory.Set ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1000]"));
m_factory.Set ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
m_factory.Set ("DataRate", DataRateValue (dataRate));
// m_factory.Set ("PacketSize", UintegerValue (packetSize));
m_factory.Set ("PacketSize",StringValue ("ns3::ConstantRandomVariable[Constant=532]"));
m_factory.Set ("Interval", StringValue ("ns3::ConstantRandomVariable[Constant=0.1]"));
}
} // namespace ns3
//
// Network topology
// n0--- -----n1
using namespace ns3;
//NS_LOG_COMPONENT_DEFINE ("tcp-one-point2one-point");
int
main (int argc, char *argv[])
{
/*
///统计画图模块/
std::string fileNameWithNoExtension = "uniform";
std::string graphicsFileName = fileNameWithNoExtension + ".png";
std::string plotFileName = fileNameWithNoExtension + ".plt";
std::string plotTitle = "2-D Plot";
std::string dataTitle = "uniform-D Data";
// Instantiate the plot and set its title.
Gnuplot plot (graphicsFileName);
plot.SetTitle (plotTitle);
// Make the graphics file, which the plot file will create when it
// is used with Gnuplot, be a PNG file.
plot.SetTerminal ("png");
// Set the labels for each axis.
plot.SetLegend ("X Values", "Y Values");
// Set the range for the x axis.
plot.AppendExtra ("set xrange [1:+50]");
// Instantiate the dataset, set its title, and make the points be
// plotted along with connecting lines.
Gnuplot2dDataset dataset_interval;
dataset_interval.SetTitle (dataTitle);
dataset_interval.SetStyle (Gnuplot2dDataset::LINES_POINTS);
*/
//
// Set up some default values for the simulation.
//
LogComponentEnable("myOnOffApplication",LOG_LEVEL_INFO);
// Config::SetDefault ("ns3::myOnOffApplication::PacketSize", UintegerValue (700));
// ??? try and stick 15kb/s into the data rate
Config::SetDefault ("ns3::myOnOffApplication::DataRate", StringValue ("50Mb/s"));
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
NetDeviceContainer devices;
devices=pointToPoint.Install (nodes);
//NS_LOG_INFO ("Install internet stack on all nodes.");
InternetStackHelper stack;
stack.Install (nodes);
// NS_LOG_INFO ("Assign IP Addresses.");
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
//NS_LOG_INFO ("Create applications.");
//
// Create a packet sink on the star "hub" to receive packets.
//
uint16_t port = 50000;
Address hubLocalAddress (InetSocketAddress (Ipv4Address::GetAny (), port));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", hubLocalAddress);
ApplicationContainer hubApp = packetSinkHelper.Install (nodes.Get (1)); //接收端 n1 节点
hubApp.Start (Seconds (0.0));
hubApp.Stop (Seconds (200.0));
//
// Create OnOff applications to send TCP to the hub, one on each spoke node. //
myOnOffHelper onOffHelper ("ns3::TcpSocketFactory", Address ());
onOffHelper.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=200]"));
onOffHelper.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
onOffHelper.SetAttribute ("MaxBytes",UintegerValue(0) );
// onOffHelper.SetAttribute ("PacketSize", StringValue ("ns3::ConstantRandomVariable[Constant=137]"));
onOffHelper.SetAttribute ("PacketSize", StringValue ("ns3::UniformRandomVariable[Min=100|Max=137]"));
// onOffHelper.SetAttribute ("Interval", StringValue ("ns3::ConstantRandomVariable[Constant=2]"));
//onOffHelper.SetAttribute ("Interval", StringValue ("ns3::UniformRandomVariable[Min=1|Max=4]"));
onOffHelper.SetAttribute ("Interval", StringValue ("ns3::ExponentialRandomVariable[Mean=3.14|Bound=0.0]"));
ApplicationContainer spokeApps;
AddressValue remoteAddress (InetSocketAddress (interfaces.GetAddress(1), port)); //远端地址 也就是接收端的IP地址
onOffHelper.SetAttribute ("Remote", remoteAddress);
spokeApps.Add(onOffHelper.Install(nodes.Get(0)));
spokeApps.Start (Seconds (0.0));
spokeApps.Stop (Seconds (200.0));
//NS_LOG_INFO ("Enable static global routing.");
//
// Turn on global static routing so we can actually be routed across the star.
//
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
//NS_LOG_INFO ("Enable pcap tracing.");
//
// Do pcap tracing on all point-to-point devices on all nodes.
//
pointToPoint.EnablePcapAll ("one-point2one-point");
// NS_LOG_INFO ("Run Simulation.");
// AnimationInterface anim ("one-point2one-point.xml");
//double x1=12;
//double y1=12;
//double x2=24;
//double y2=24;
AnimationInterface::SetConstantPosition (nodes.Get(0),12,12);
AnimationInterface::SetConstantPosition (nodes.Get(1),24,24);
AnimationInterface anim ("one-point2one-point.xml");
anim.EnablePacketMetadata();
画图
// Add the dataset to the plot.
plot.SetTitle (plotTitle);
// Make the graphics file, which the plot file will create when it
// is used with Gnuplot, be a PNG file.
plot.SetTerminal ("png");
// Set the labels for each axis.
plot.SetLegend ("X Values", "Y Values");
// Set the range for the x axis.
plot.AppendExtra ("set xrange [1:+50]");
/*
plot.AddDataset (dataset_interval);
// Open the plot file.
std::ofstream plotFile (plotFileName.c_str());
// Write the plot file.
plot.GenerateOutput (plotFile);
// Close the plot file.
plotFile.close();
*/
Simulator::Run ();
sort(data_interval,data_interval+48);
for (int i=0;i<48;i++)
{
dataset_interval.Add(i,data_interval[i]);
dataset_packetsize.Add(i,data_packetsize[i]);
}
// dataset_interval.Add(count_packets,myinterval);
plot.AddDataset (dataset_interval);
// Open the plot file.
std::ofstream plotFile (plotFileName.c_str());
// Write the plot file.
plot.GenerateOutput (plotFile);
// Close the plot file.
plotFile.close();
//
plot2.SetTitle (plotTitle2);
// Make the graphics file, which the plot file will create when it
// is used with Gnuplot, be a PNG file.
plot2.SetTerminal ("png");
// Set the labels for each axis.
plot2.SetLegend ("X Values", "Y Values");
// Set the range for the x axis.
plot2.AppendExtra ("set xrange [-5:+60]");
plot2.AppendExtra ("set yrange [60:+200]");
plot2.AddDataset (dataset_packetsize);
std::ofstream plotFile2 (plotFileName2.c_str());
// Write the plot file.
plot2.GenerateOutput (plotFile2);
// Close the plot file.
plotFile2.close();
Simulator::Destroy ();
// NS_LOG_INFO ("Done.");
return 0;
}