#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
using namespace ns3;
void showRoutingTable(int time)
{
char name[50];
sprintf(name, "scratch/RoutingTable-%d.txt",time);
Ipv4GlobalRoutingHelper().PrintRoutingTableAllAt(Seconds(time), Create<OutputStreamWrapper>(name, std::ios::out));
}
void directUdp(Ptr<Node> sender, Ptr<Node> recver, Ipv4Address recverAddr, double lastTime = -1)
{
const int port = 1314;
UdpEchoServerHelper s(port);
ApplicationContainer sa = s.Install(recver);
sa.Start(Seconds(0.01));
UdpEchoClientHelper c(recverAddr, port);
c.SetAttribute("Interval", TimeValue(Seconds(0.5)));
c.SetAttribute("PacketSize", UintegerValue(1024));
ApplicationContainer ca = c.Install(sender);
ca.Start(Seconds(0.02));
if (lastTime > 0.01)
{
sa.Stop(Seconds(lastTime));
ca.Stop(Seconds(lastTime));
}
}
Ptr<Ipv4StaticRouting> GetRT(Ptr<Node> node) {
static Ipv4StaticRoutingHelper routingHelper;
return routingHelper.GetStaticRouting(node->GetObject<Ipv4>());
}
int GetIface(Ptr<Node> node, int deviceIdx)
{
return node->GetObject<Ipv4>()->GetInterfaceForDevice(node->GetDevice(deviceIdx));
}
int main(int argc, char** argv)
{
CommandLine cmd;
cmd.Parse(argc, argv);
NodeContainer A, B, C;
A.Create(3);
B.Create(1);
C.Create(1);
InternetStackHelper is;
is.Install(A);
is.Install(B);
is.Install(C);
B.Add(A.Get(1));
C.Add(A.Get(2));
Ipv4AddressHelper ipv4;
ipv4.SetBase("1.0.0.0", "255.0.0.0");
CsmaHelper csma;
csma.SetChannelAttribute("DataRate", DataRateValue(DataRate(5000000)));
csma.SetChannelAttribute("Delay", TimeValue(MilliSeconds(2)));
Ipv4InterfaceContainer a = ipv4.Assign(csma.Install(A)), b, c;
PointToPointHelper p2p;
p2p.SetDeviceAttribute("DataRate", DataRateValue(DataRate("1Gbps")));
p2p.SetDeviceAttribute("Mtu", UintegerValue(1500));
p2p.SetChannelAttribute("Delay", TimeValue(Seconds(0.01)));
ipv4.SetBase("2.0.0.0", "255.0.0.0");
b = ipv4.Assign(p2p.Install(B.Get(1), B.Get(0)));
ipv4.SetBase("3.0.0.0", "255.0.0.0");
c = ipv4.Assign(p2p.Install(C.Get(1), C.Get(0)));
showRoutingTable(0);
GetRT(A.Get(0))->AddNetworkRouteTo("2.0.0.0", "255.0.0.0", 1);
GetRT(A.Get(0))->AddNetworkRouteTo("3.0.0.0", "255.0.0.0", 1);
GetRT(A.Get(2))->AddNetworkRouteTo("2.0.0.0", "255.0.0.0", 1);
GetRT(A.Get(1))->AddNetworkRouteTo("3.0.0.0", "255.0.0.0", 1);
GetRT(C.Get(0))->AddNetworkRouteTo("1.0.0.0", "255.0.0.0", 1);
GetRT(B.Get(0))->AddNetworkRouteTo("3.0.0.0", "255.0.0.0", 1);
std::cout<<A.Get(0)->GetId()<<' '<<B.Get(0)->GetId()<<' '<<b.GetAddress(1)<<std::endl;
std::cout<<A.Get(0)->GetId()<<' '<<A.Get(1)->GetId()<<' '<<b.GetAddress(0)<<std::endl;
// directUdp(A.Get(0), B.Get(0), b.GetAddress(1));
// directUdp(A.Get(0), A.Get(1), a.GetAddress(1));
// directUdp(B.Get(1), B.Get(0), b.GetAddress(1));
// directUdp(A.Get(0), C.Get(0), c.GetAddress(1));
directUdp(C.Get(0), A.Get(0), a.GetAddress(0));
// directUdp(B.Get(0), C.Get(0), c.GetAddress(1));
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor;
monitor = flowmon.InstallAll ();
Simulator::Run();
Simulator::Destroy();
monitor->CheckForLostPackets ();
Ptr<Ipv4FlowClassifier> classifier = DynamicCast<Ipv4FlowClassifier> (flowmon.GetClassifier ());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats ();
std::cout << "source destination throughput loss trPacketNumber aveDelay aveJitter" << std::endl;
for (std::map<FlowId, FlowMonitor::FlowStats>::const_iterator i = stats.begin (); i != stats.end (); ++i)
{
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow (i->first);
double throughput =i->second.rxBytes * 8.0 / (10*1024*1024); //Mbps
double loss = i->second.txPackets - i->second.rxPackets; //个
double trPacketNumber =i->second.txPackets; //个
std::cout << t.sourceAddress << " ";
std::cout << t.destinationAddress << " ";
std::cout << throughput << " ";
std::cout << loss << " ";
std::cout << trPacketNumber << " ";
std::cout << i->second.delaySum.GetSeconds() / i->second.rxPackets << " "; //平均时延
std::cout << i->second.jitterSum.GetSeconds() / i->second.rxPackets << "\n"; //平均抖动
}
return 0;
}