Hi everyone,
I wrote a code for a store carry and forward mechanism that saves data when it is out of the receiver's range and dequeues it when the connection is re-established. However, I don't see any difference between the queuing and the normal scenario. I think something might be wrong with my queuing implementation. Could you please help me?
Thank you,
#include "ns3/aodv-module.h"
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/network-module.h"
#include "ns3/wifi-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/queue.h"
#include "ns3/drop-tail-queue.h"
#include <queue>
#include <map>
#include <set>
using namespace ns3;
// Global variables to track packet counts and throughput
uint32_t totalPacketsSent = 0;
uint32_t totalPacketsReceived = 0;
uint64_t totalBytesReceived = 0;
std::map<uint32_t, Ptr<DropTailQueue<Packet>>> packetQueues;
void RxCallback(Ptr<Socket> socket) {
Ptr<Packet> packet;
Address senderAddress;
while ((packet = socket->RecvFrom(senderAddress))) {
uint32_t packetSize = packet->GetSize();
totalBytesReceived += packetSize;
totalPacketsReceived++;
InetSocketAddress inetAddr = InetSocketAddress::ConvertFrom(senderAddress);
Ipv4Address senderIpv4 = inetAddr.GetIpv4();
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s: Packet received from " << senderIpv4);
}
}
Ptr<Socket> SetupPacketReceive(Ipv4Address addr, Ptr<Node> node) {
TypeId tid = TypeId::LookupByName("ns3::UdpSocketFactory");
Ptr<Socket> sink = Socket::CreateSocket(node, tid);
InetSocketAddress local = InetSocketAddress(addr, 9);
sink->Bind(local);
sink->SetRecvCallback(MakeCallback(&RxCallback));
return sink;
}
void SendQueuedPacketsToNode4(uint32_t nodeId) {
while (!packetQueues[nodeId]->IsEmpty()) {
Ptr<Packet> dequeuedPacket = packetQueues[nodeId]->Dequeue();
if (dequeuedPacket) {
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s: Packet dequeued and sent from Node " << nodeId);
}
}
}
void SendDataToNode4(NodeContainer nodes, ApplicationContainer apps) {
for (uint32_t i = 0; i < nodes.GetN() - 1; ++i) {
Vector positionI = nodes.Get(i)->GetObject<MobilityModel>()->GetPosition();
Vector position4 = nodes.Get(4)->GetObject<MobilityModel>()->GetPosition();
double distanceToReceiver = CalculateDistance(positionI, position4);
if (distanceToReceiver < 100.0) {
for (uint32_t j = 0; j < apps.GetN(); ++j) {
Ptr<OnOffApplication> app = DynamicCast<OnOffApplication>(apps.Get(j));
Ptr<Packet> packet = Create<Packet>(1480);
SendQueuedPacketsToNode4(i);
totalPacketsSent++;
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s: Packet sent from Node " << i);
}
} else {
for (uint32_t j = 0; j < apps.GetN(); ++j) {
Ptr<OnOffApplication> app = DynamicCast<OnOffApplication>(apps.Get(j));
Ptr<Packet> packet = Create<Packet>(1480);
bool success = packetQueues[i]->Enqueue(packet);
if (success) {
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s: Packet queued at Node " << i << " (Distance to receiver: " << distanceToReceiver << " meters)");
} else {
NS_LOG_UNCOND(Simulator::Now().GetSeconds() << "s: Queue full, packet dropped at Node " << i);
}
totalPacketsSent++;
}
}
}
// Re-schedule data transmission
Simulator::Schedule(Seconds(1.0), &SendDataToNode4, nodes, apps);
}
void CalculateMetrics() {
double packetRatio = static_cast<double>(totalPacketsReceived) / totalPacketsSent;
double averageThroughputBps = (totalBytesReceived * 8) / Simulator::Now().GetSeconds();
double averageThroughputKbps = averageThroughputBps / 1000.0;
NS_LOG_UNCOND("Packet Delivery Ratio: " << packetRatio);
NS_LOG_UNCOND("Average Throughput: " << averageThroughputKbps << " kbps");
}
int main() {
RngSeedManager::SetSeed(1843);
LogComponentDisableAll(LOG_LEVEL_ALL);
NodeContainer nodes;
nodes.Create(5);
WifiHelper wifi;
wifi.SetStandard(WIFI_STANDARD_80211a);
wifi.SetRemoteStationManager("ns3::IdealWifiManager");
YansWifiPhyHelper wifiPhy;
wifiPhy.Set("TxPowerStart", DoubleValue(7.0));
wifiPhy.Set("TxPowerEnd", DoubleValue(7.0));
YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay("ns3::ConstantSpeedPropagationDelayModel");
wifiChannel.AddPropagationLoss("ns3::FriisPropagationLossModel");
wifiPhy.SetChannel(wifiChannel.Create());
WifiMacHelper wifiMac;
wifiMac.SetType("ns3::AdhocWifiMac");
NetDeviceContainer devices = wifi.Install(wifiPhy, wifiMac, nodes);
wifiPhy.EnablePcap("simulation", devices);
std::string traceFile = "paths2/mtcp/mTSPPaths_a400_Ns4.ns_movements";
Ns2MobilityHelper ns2 = Ns2MobilityHelper(traceFile);
ns2.Install();
InternetStackHelper stack;
stack.Install(nodes);
Ipv4AddressHelper address;
address.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign(devices);
uint16_t port = 9;
OnOffHelper onoff1("ns3::UdpSocketFactory", Address());
onoff1.SetAttribute("PacketSize", UintegerValue(1480));
onoff1.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
onoff1.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
onoff1.SetAttribute("DataRate", StringValue("100kbps"));
for (uint32_t i = 0; i < nodes.GetN(); ++i) {
Ptr<DropTailQueue<Packet>> queue = CreateObject<DropTailQueue<Packet>>();
queue->SetMaxSize(QueueSize(QueueSizeUnit::PACKETS, 10000000));
packetQueues[i] = queue;
}
ApplicationContainer apps;
for (int i = 0; i <= 3; i++) {
Ptr<Socket> sink = SetupPacketReceive(interfaces.GetAddress(4), nodes.Get(4));
AddressValue remoteAddress(InetSocketAddress(interfaces.GetAddress(4), port));
onoff1.SetAttribute("Remote", remoteAddress);
Ptr<UniformRandomVariable> var = CreateObject<UniformRandomVariable>();
ApplicationContainer temp = onoff1.Install(nodes.Get(i));
temp.Start(Seconds(var->GetValue(1.0, 1.1)));
temp.Stop(Seconds(540.0));
apps.Add(temp);
}
Simulator::Schedule(Seconds(5.0), &SendDataToNode4, nodes, apps);
Simulator::Schedule(Seconds(600.0), &CalculateMetrics);
Simulator::Stop(Seconds(600.0));
FlowMonitorHelper flowMonitor;
Ptr<FlowMonitor> monitor = flowMonitor.InstallAll();
Simulator::Run();
monitor->CheckForLostPackets();
FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();
double totalEndToEndDelay = 0.0;
double totalEndToEndJitter = 0.0;
int totalFlowsWithData = 0;
for (auto &iter : stats) {
FlowMonitor::FlowStats flowStats = iter.second;
if (flowStats.rxPackets > 3) {
double averageEndToEndDelay = flowStats.delaySum.GetSeconds() / flowStats.rxPackets;
double averageJitter = flowStats.jitterSum.GetSeconds() / (flowStats.rxPackets - 1);
totalEndToEndDelay += averageEndToEndDelay;
totalEndToEndJitter += averageJitter;
totalFlowsWithData++;
}
}
if (totalFlowsWithData > 0) {
totalEndToEndDelay /= totalFlowsWithData;
totalEndToEndJitter /= totalFlowsWithData;
std::cout << "Total End-to-End Delay: " << totalEndToEndDelay << " seconds" << std::endl;
std::cout << "Total End-to-End Jitter: " << totalEndToEndJitter << " seconds" << std::endl;
} else {
std::cout << "No flows with received packets." << std::endl;
}
NS_LOG_UNCOND("Total Packets Sent: " << totalPacketsSent);
NS_LOG_UNCOND("Total Packets Received: " << totalPacketsReceived);
Simulator::Destroy();
return 0;
}