Skip to main content

Performance Analysis of TCP Reno Congestion Control Under Varying Round-Trip Time Conditions | NS3 Project 14

Performance Analysis of TCP Reno Congestion Control Under Varying Round-Trip Time Conditions: An ns-3 Simulation Study

PROMPT

Part 1:

You are an expert in ns-3 network simulation and C++.
I want you to design and implement a complete ns-3 simulation in C++ to analyze the performance of TCP Reno over a point-to-point link with varying RTT values (10 ms to 200 ms).

Requirements:

  1. Simulation Setup
    • Create a point-to-point network topology (2 nodes).
    • Configure link parameters such as:
      • Data rate (choose a reasonable default like 5 Mbps or 10 Mbps)
      • Packet size
      • Queue type (DropTail or similar)
    • Use TCP Reno as the transport protocol.
    • Ensure RTT variation is achieved by modifying propagation delay (range: 10 ms to 200 ms in steps).
  2. Traffic Configuration
    • Use a TCP application (e.g., BulkSendApplication or OnOffApplication).
    • Configure a receiver using PacketSink.
    • Run simulations for multiple RTT values.
  3. Metrics to Analyze
    Collect and output the following:
    • Throughput
    • Packet loss
    • End-to-end delay
    • Congestion window (cwnd) behavior over time
  4. Tracing and Logging
    • Enable trace files for:
      • Congestion window (cwnd)
      • Packet drops
      • Throughput
    • Generate a trace matrix (trace files/logs) that can be used for analysis.
  5. NetAnim Visualization
    • Integrate NetAnim:
      • Generate an XML animation file.
      • Ensure node positions and packet flows are visible.
  6. PCAP / Wireshark Support
    • Enable PCAP tracing so that the simulation output can be analyzed in Wireshark.
    • Clearly mention how to open and inspect the generated PCAP files.
  7. Graph Generation (Gnuplot)
    • Generate output files compatible with Gnuplot.
    • Provide scripts or instructions to plot:
      • RTT vs Throughput
      • RTT vs Packet Loss
      • Time vs Congestion Window
  8. Code Structure
    • Write clean, modular C++ code compatible with ns-3.
    • Include comments explaining each section.
    • Ensure the code compiles and runs without errors.
  9. Execution Instructions
    After writing the code, provide:
    • Steps to compile and run the simulation in ns-3
    • Commands to enable tracing
    • Steps to view:
      • NetAnim visualization
      • Wireshark (PCAP files)
      • Gnuplot graphs
  10. Expected Output Explanation
    • Briefly explain what trends are expected when RTT increases (e.g., effect on throughput and cwnd).

Part 2:

You are an expert in ns-3 and C++.
I have already implemented a TCP Reno RTT analysis simulation in ns-3. Now I want you to update and refine the existing implementation with the following changes:

1. Integrate FlowMonitor

Enhance the simulation by adding FlowMonitor to collect detailed performance metrics.
Include FlowMonitor module: #include "ns3/flow-monitor-module.h"

  • Install FlowMonitor on all nodes.
  • Collect and compute:
    • Throughput per flow
    • Packet loss
    • Delay statistics
  • Output results in a readable format (console + optional XML file).

2. Output Enhancements

  • Ensure FlowMonitor results are:
    • Printed clearly after simulation ends
    • Optionally exported to an XML file (e.g., flowmon.xml)

3. Maintain Existing Features

Make sure the following features remain intact:

  • RTT variation (10 ms to 200 ms)
  • NetAnim XML generation
  • PCAP tracing (for Wireshark)
  • Trace files (cwnd, drops, etc.)
  • Gnuplot-compatible output

4. Code Quality

  • Keep the code modular and well-commented
  • Avoid redundancy while integrating FlowMonitor
  • Ensure compatibility with standard ns-3 versions

5. Execution Instructions Update

Update the run instructions to reflect:

  • New filename (tcp-reno-rtt-analysis.cc)
  • FlowMonitor output usage
  • Any new compilation flags if required

CODE:

/* =================================================================== 
* TCP Reno Performance Analysis over a Point-to-Point Link with Varying RTT 
* ns-3 version : 3.42 
* Author ID    : 24BPS1135 
* ─────────────────────────────────────────────────────────────────────
* TOPOLOGY  (one instance per simulation run) 
* ───────────────────────────────────────────────────────────────────── 
*   n0 (BulkSend) ──────[P2P  10 Mbps | delay = RTT/2]────── n1 (PacketSink) 
* ──────────────────────────────────────────────────────────────────── 
* WHAT THIS SIMULATION DOES 
* ───────────────────────────────────────────────────────────────────── 
*   Sweeps RTT values {10, 25, 50, 75, 100, 125, 150, 175, 200} ms by running 
*   9 back-to-back ns-3 simulations. Each run collects: 
* 
*   Via FlowMonitor 
*     • Throughput (Mbps) 
*     • Goodput (Mbps)          – application-layer useful bytes / time 
*     • Packet loss ratio 
*     • Average / min / max end-to-end delay (ms) 
*     • Mean jitter (ms) 
*     • Tx / Rx packet & byte counts 
* 
*   Via trace callbacks 
*     • Congestion window over time  →  cwnd_rtt_Xms.dat 
* ──────────────────────────────────────────────────────────────────── 
* OUTPUT FILES   (all written to scratch/results/) 
* ───────────────────────────────────────────────────────────────────── 
*   summary.dat                RTT | Throughput | Goodput | Loss | Delay | Jitter 
*   cwnd_rtt_Xms.dat          Time(s) | cwnd(segments)        – one file per RTT 
*   flowmon_rtt_Xms.xml        FlowMonitor XML export            – one file per RTT 
*   tcp-reno-rtt-Xms.tr        ASCII link-level trace            – one file per RTT 
*   tcp-reno-rtt-0-0.pcap      Sender   PCAP  (RTT = 10 ms only) 
*   tcp-reno-rtt-0-1.pcap      Receiver PCAP  (RTT = 10 ms only) 
*   tcp-reno-netanim.xml      NetAnim animation  (RTT = 10 ms only) 
* ──────────────────────────────────────────────────────────────────── 
* COMPILE & RUN  (from the ns-3 root directory) 
* ────────────────────────────────────────────────────────────────────
*   mkdir -p scratch/results 
*   ./ns3 build scratch/24BPS1135 
*   ./ns3 run   scratch/24BPS1135 
* 
* VISUALISE 
*   Wireshark  : wireshark scratch/results/tcp-reno-rtt-0-0.pcap 
*   NetAnim    : ./netanim-3.109/NetAnim  →  open tcp-reno-netanim.xml 
*   FlowMonitor: open scratch/results/flowmon_rtt_Xms.xml in any XML viewer 
*   Gnuplot    : gnuplot scratch/plot_throughput.plt 
*                gnuplot scratch/plot_loss.plt 
*                gnuplot scratch/plot_cwnd.plt 
* ===================================================================== */

// ── Standard library ──────────────────────────────────────────────────────────
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <sys/stat.h>       // POSIX mkdir(2)

// ── ns-3 modules ──────────────────────────────────────────────────────────────
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/flow-monitor-module.h"   // FlowMonitor – per-flow statistics
#include "ns3/internet-module.h"
#include "ns3/netanim-module.h"        // NetAnim XML animation
#include "ns3/network-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/traffic-control-module.h"

using namespace ns3;

NS_LOG_COMPONENT_DEFINE("24BPS1135");

// =============================================================================
//  GLOBAL STATE
// =============================================================================
static std::ofstream g_cwndStream;
static std::ofstream g_summaryStream;
static uint32_t g_segmentSize = 1024; // bytes

// =============================================================================
//  TRACE CALLBACKS
// =============================================================================
static void
CwndChange(uint32_t /* oldCwnd */, uint32_t newCwnd)
{
    g_cwndStream << std::fixed << std::setprecision(6)
                 << Simulator::Now().GetSeconds()                   << "\t"
                 << static_cast<double>(newCwnd) / g_segmentSize   << "\n";
}

// =============================================================================
//  HELPER: connect the cwnd trace source after the TCP socket exists
// =============================================================================
static void
ConnectCwndTrace()
{
    Config::ConnectWithoutContext(
        "/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow",
        MakeCallback(&CwndChange));
}

// =============================================================================
//  FLOWMONITOR REPORTING
// =============================================================================
static void
PrintFlowMonitorStats(Ptr<FlowMonitor>       monitor,
                      FlowMonitorHelper&     flowHelper,
                      uint32_t               port,
                      uint32_t               rttMs,
                      const std::string&     xmlFile,
                      double&                tput,
                      double&                loss,
                      double&                delay,
                      double&                jitter)
{
    monitor->CheckForLostPackets();
    monitor->SerializeToXmlFile(xmlFile, true, true);
    std::cout << "    FlowMonitor XML → " << xmlFile << "\n";

    Ptr<Ipv4FlowClassifier> classifier =
        DynamicCast<Ipv4FlowClassifier>(flowHelper.GetClassifier());
    FlowMonitor::FlowStatsContainer stats = monitor->GetFlowStats();

    std::cout << "\n"
              << "    ┌─────────────────────────────────────────────────┐\n"
              << "    │  FlowMonitor Report  –  RTT = " << std::setw(4) << rttMs
              << " ms                 │\n"
              << "    └─────────────────────────────────────────────────┘\n";

    bool flowFound = false;
    for (auto& kv : stats)
    {
        Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(kv.first);
        if (t.destinationPort != port)
            continue;

        flowFound = true;
        const FlowMonitor::FlowStats& fs = kv.second;

        double durationSec = (fs.timeLastRxPacket - fs.timeFirstRxPacket).GetSeconds();
        double throughputMbps = 0.0;
        if (durationSec > 0.0)
            throughputMbps = (static_cast<double>(fs.rxBytes) * 8.0) / (durationSec * 1.0e6);

        const uint32_t hdrBytes = 40;
        double payloadBytes = (fs.rxBytes > fs.rxPackets * hdrBytes)
                              ? static_cast<double>(fs.rxBytes - fs.rxPackets * hdrBytes)
                              : static_cast<double>(fs.rxBytes);
        double goodputMbps = 0.0;
        if (durationSec > 0.0)
            goodputMbps = (payloadBytes * 8.0) / (durationSec * 1.0e6);

        double lossRatio = 0.0;
        if (fs.txPackets > 0)
            lossRatio = static_cast<double>(fs.lostPackets) / static_cast<double>(fs.txPackets);

        double avgDelayMs = 0.0;
        if (fs.rxPackets > 0)
            avgDelayMs = (fs.delaySum.GetSeconds() * 1000.0) / static_cast<double>(fs.rxPackets);

        double meanJitterMs = 0.0;
        if (fs.rxPackets > 1)
            meanJitterMs = (fs.jitterSum.GetSeconds() * 1000.0) / static_cast<double>(fs.rxPackets - 1);

        std::cout << std::fixed
                  << "    Flow ID      : " << kv.first << "\n"
                  << "    Src → Dst    : "
                  << t.sourceAddress      << ":" << t.sourcePort << "  →  "
                  << t.destinationAddress << ":" << t.destinationPort << "\n"
                  << "    Protocol     : "
                  << (t.protocol == 6 ? "TCP" : "UDP") << "\n"
                  << "    ─── Packet counters ──────────────────────────────\n"
                  << "    Tx packets   : " << fs.txPackets  << "\n"
                  << "    Rx packets   : " << fs.rxPackets  << "\n"
                  << "    Lost packets : " << fs.lostPackets
                  << "  (" << std::setprecision(4) << lossRatio * 100.0 << " %)\n"
                  << "    Tx bytes     : " << fs.txBytes    << "\n"
                  << "    Rx bytes     : " << fs.rxBytes    << "\n"
                  << "    ─── Throughput ───────────────────────────────────\n"
                  << "    Throughput   : " << std::setprecision(4)
                                          << throughputMbps << " Mbps\n"
                  << "    Goodput      : " << std::setprecision(4)
                                          << goodputMbps   << " Mbps\n"
                  << "    ─── Delay (end-to-end) ───────────────────────────\n"
                  << "    Avg delay    : " << std::setprecision(3)
                                          << avgDelayMs    << " ms\n"
                  << "    (min/max per-pkt delay not tracked by ns-3 FlowStats)\n"
                  << "    ─── Jitter ───────────────────────────────────────\n"
                  << "    Mean jitter  : " << std::setprecision(3)
                                          << meanJitterMs  << " ms\n";

        tput   = throughputMbps;
        loss   = lossRatio;
        delay  = avgDelayMs;
        jitter = meanJitterMs;
    }

    if (!flowFound)
    {
        std::cout << "    WARNING: no matching flow found (port " << port << ")\n";
    }
}

// =============================================================================
//  RunSimulation
// =============================================================================
static void
RunSimulation(uint32_t           rttMs,
              bool               enablePcap,
              bool               enableNetAnim,
              const std::string& resultsDir)
{
    const double   simTime   = 30.0;
    const uint32_t port      = 9;
    const uint32_t halfRttMs = rttMs / 2;
    g_segmentSize = 1024;

    std::cout << "\n╔══════════════════════════════════════════════════╗\n"
              << "║  RTT = " << std::setw(4) << rttMs
              << " ms   (one-way delay = " << std::setw(3) << halfRttMs
              << " ms)          ║\n"
              << "╚══════════════════════════════════════════════════╝\n";

    Config::SetDefault("ns3::TcpL4Protocol::SocketType",
                       TypeIdValue(TypeId::LookupByName("ns3::TcpLinuxReno")));
    Config::SetDefault("ns3::TcpL4Protocol::RecoveryType",
                       TypeIdValue(TypeId::LookupByName("ns3::TcpClassicRecovery")));
    Config::SetDefault("ns3::TcpSocket::SndBufSize",  UintegerValue(1 << 20));
    Config::SetDefault("ns3::TcpSocket::RcvBufSize",  UintegerValue(1 << 20));
    Config::SetDefault("ns3::TcpSocket::SegmentSize", UintegerValue(g_segmentSize));
    Config::SetDefault("ns3::TcpSocket::InitialCwnd", UintegerValue(1));
    Config::SetDefault("ns3::TcpSocket::DelAckCount", UintegerValue(1));
    Config::SetDefault("ns3::TcpSocketBase::Sack",    BooleanValue(false));

    NodeContainer nodes;
    nodes.Create(2);

    std::ostringstream delayOss;
    delayOss << halfRttMs << "ms";

    PointToPointHelper p2p;
    p2p.SetDeviceAttribute ("DataRate", StringValue("10Mbps"));
    p2p.SetChannelAttribute("Delay",    StringValue(delayOss.str()));
    p2p.SetQueue("ns3::DropTailQueue", "MaxSize", StringValue("100p"));
    NetDeviceContainer devices = p2p.Install(nodes);

    InternetStackHelper internet;
    internet.Install(nodes);

    Ipv4AddressHelper ipv4;
    ipv4.SetBase("10.1.1.0", "255.255.255.0");
    Ipv4InterfaceContainer interfaces = ipv4.Assign(devices);

    Address receiverAddr(InetSocketAddress(interfaces.GetAddress(1), port));

    BulkSendHelper bulkSend("ns3::TcpSocketFactory", receiverAddr);
    bulkSend.SetAttribute("MaxBytes", UintegerValue(0));
    bulkSend.SetAttribute("SendSize", UintegerValue(g_segmentSize));
    ApplicationContainer senderApps = bulkSend.Install(nodes.Get(0));
    senderApps.Start(Seconds(1.0));
    senderApps.Stop (Seconds(simTime));

    PacketSinkHelper packetSink("ns3::TcpSocketFactory",
                                InetSocketAddress(Ipv4Address::GetAny(), port));
    ApplicationContainer sinkApps = packetSink.Install(nodes.Get(1));
    sinkApps.Start(Seconds(0.5));
    sinkApps.Stop (Seconds(simTime + 1.0));

    std::ostringstream cwndFilename;
    cwndFilename << resultsDir << "/cwnd_rtt_" << rttMs << "ms.dat";
    g_cwndStream.open(cwndFilename.str());
    g_cwndStream << "# Time(s)\tcwnd(segments)   [RTT=" << rttMs << "ms]\n";

    Simulator::Schedule(Seconds(1.001), &ConnectCwndTrace);

    FlowMonitorHelper flowHelper;
    Ptr<FlowMonitor>  monitor = flowHelper.InstallAll();

    AsciiTraceHelper ascii;
    std::string trFilename = resultsDir + "/tcp-reno-rtt-" + std::to_string(rttMs) + "ms.tr";
    p2p.EnableAsciiAll(ascii.CreateFileStream(trFilename));

    if (enablePcap)
    {
        std::string pcapPrefix = resultsDir + "/tcp-reno-rtt";
        p2p.EnablePcapAll(pcapPrefix, false);
    }

    AnimationInterface* anim = nullptr;
    if (enableNetAnim)
    {
        std::string animFilename = resultsDir + "/tcp-reno-netanim.xml";
        anim = new AnimationInterface(animFilename);
        anim->SetConstantPosition(nodes.Get(0), 10.0, 30.0);
        anim->SetConstantPosition(nodes.Get(1), 70.0, 30.0);
        anim->UpdateNodeDescription(nodes.Get(0), "n0  Sender (BulkSend)");
        anim->UpdateNodeDescription(nodes.Get(1), "n1  Receiver (PacketSink)");
        anim->UpdateNodeSize(nodes.Get(0)->GetId(), 4.0, 4.0);
        anim->UpdateNodeSize(nodes.Get(1)->GetId(), 4.0, 4.0);
        anim->EnablePacketMetadata(true);
    }

    Simulator::Stop(Seconds(simTime + 2.0));
    Simulator::Run();

    std::string xmlFile = resultsDir + "/flowmon_rtt_" + std::to_string(rttMs) + "ms.xml";
    double throughputMbps = 0.0;
    double lossRatio      = 0.0;
    double avgDelayMs     = 0.0;
    double meanJitterMs   = 0.0;

    PrintFlowMonitorStats(monitor, flowHelper, port, rttMs, xmlFile, throughputMbps, lossRatio, avgDelayMs, meanJitterMs);

    g_summaryStream << std::fixed << std::setprecision(6)
                    << rttMs          << "\t"
                    << throughputMbps << "\t"
                    << lossRatio      << "\t"
                    << avgDelayMs     << "\t"
                    << meanJitterMs   << "\n";
    g_summaryStream.flush();

    g_cwndStream.close();
    if (anim)
    {
        delete anim;
        anim = nullptr;
    }
    Simulator::Destroy();
}

// =============================================================================
//  main
// =============================================================================
int
main(int argc, char* argv[])
{
    std::vector<uint32_t> rttValues = {10, 25, 50, 75, 100, 125, 150, 175, 200};
    const std::string resultsDir = "scratch/results";

    ::mkdir(resultsDir.c_str(), 0755);

    const std::string summaryPath = resultsDir + "/summary.dat";
    g_summaryStream.open(summaryPath);
    if (!g_summaryStream.is_open())
    {
        std::cerr << "ERROR: cannot open " << summaryPath << "\n"
                  << "Ensure scratch/results/ exists and is writable.\n";
        return 1;
    }

    g_summaryStream << "# RTT_ms\tThroughput_Mbps\tLossRatio\tAvgDelay_ms\tMeanJitter_ms\n";

    std::cout << "╔══════════════════════════════════════════════════════════╗\n"
              << "║          TCP Reno RTT Analysis  –  ns-3 v3.42            ║\n"
              << "║                    ID: 24BPS1135                         ║\n"
              << "╠══════════════════════════════════════════════════════════╣\n"
              << "║  Topology    n0 (BulkSend) ──[P2P 10 Mbps]── n1 (Sink) ║\n"
              << "║  TCP          TcpLinuxReno  (classic AIMD)               ║\n"
              << "║  MSS          " << std::setw(4) << g_segmentSize << " bytes                                   ║\n"
              << "║  Sim time    30 s per run                                ║\n"
              << "║  RTT values  10 25 50 75 100 125 150 175 200  ms         ║\n"
              << "║  Results     " << resultsDir << "/                        ║\n"
              << "╚══════════════════════════════════════════════════════════╝\n";

    for (std::size_t i = 0; i < rttValues.size(); ++i)
    {
        const bool firstRun = (i == 0);
        RunSimulation(rttValues[i], firstRun, firstRun, resultsDir);
    }
    g_summaryStream.close();

    std::cout << "\n╔══════════════════════════════════════════════════════════════════════╗\n"
              << "║                         FINAL RESULTS SUMMARY                        ║\n"
              << "╠══════════════════════════════════════════════════════════════════════╣\n"
              << "║ "
              << std::left  << std::setw(9)  << "RTT(ms)"
              << std::setw(18) << "Throughput(Mbps)"
              << std::setw(12) << "Loss Ratio"
              << std::setw(15) << "Avg Delay(ms)"
              << std::setw(15) << "Jitter(ms)"
              << " ║\n"
              << "╠══════════════════════════════════════════════════════════════════════╣\n";

    std::ifstream fin(summaryPath);
    std::string line;
    while (std::getline(fin, line))
    {
        if (line.empty() || line[0] == '#')
            continue;
        std::istringstream iss(line);
        uint32_t rtt;
        double tp, lr, ad, jt;
        if (!(iss >> rtt >> tp >> lr >> ad >> jt))
            continue;
        std::cout << "║ "
                  << std::left  << std::setw(9)  << rtt
                  << std::fixed << std::setprecision(4)
                  << std::setw(18) << tp
                  << std::setprecision(6)
                  << std::setw(12) << lr
                  << std::setprecision(3)
                  << std::setw(15) << ad
                  << std::setw(15) << jt
                  << " ║\n";
    }
    std::cout << "╚══════════════════════════════════════════════════════════════════════╝\n\n"
              << "╔══════════════════════════════════════════════════════════════════════╗\n"
              << "║                         OUTPUT FILES                                 ║\n"
              << "╠══════════════════════════════════════════════════════════════════════╣\n"
              << "║  summary.dat              RTT, Throughput, Loss, Delay, Jitter       ║\n"
              << "║  cwnd_rtt_Xms.dat          Congestion window trace  (9 files)        ║\n"
              << "║  flowmon_rtt_Xms.xml       FlowMonitor XML export   (9 files)        ║\n"
              << "║  tcp-reno-rtt-Xms.tr       ASCII link traces         (9 files)       ║\n"
              << "║  tcp-reno-rtt-0-0.pcap    Sender PCAP     (RTT=10ms, Wireshark)      ║\n"
              << "║  tcp-reno-rtt-0-1.pcap    Receiver PCAP  (RTT=10ms, Wireshark)      ║\n"
              << "║  tcp-reno-netanim.xml     NetAnim animation (RTT=10ms)               ║\n"
              << "╠══════════════════════════════════════════════════════════════════════╣\n";

    return 0;
}

Output :

Terminal Output 1 Terminal Output 2 Terminal Output 3 Terminal Output 4 Terminal Output 5 Terminal Output 6 Terminal Output 7

NetAnim:

NetAnim Visualization (tcp-reno-netanim.xml)

NetAnim displays two nodes — n0 (Sender) on the left and n1 (Receiver) on the right — connected by a link, with animated dots representing packets flowing between them during the simulation. It provides a visual confirmation that data transmission is occurring correctly and that the TCP connection is active between the two endpoints.

NetAnim Visualization 1 NetAnim Visualization 2 NetAnim Visualization 3

Comparison Data File

This .dat file is a referral file to plot the Gnuplot graphs:

Comparison Data File Summary

Gnuplot Graphs

RTT vs Packet Loss Graph (loss_vs_rtt.png)

This graph plots RTT against the packet loss ratio, showing a gradual upward trend as RTT increases. Higher RTT causes a larger Bandwidth-Delay Product, which overflows the fixed-size DropTail queue more easily, resulting in more frequent packet drops.

RTT vs Packet Loss Graph 1 RTT vs Packet Loss Graph 2

RTT vs Throughput Graph (throughput_vs_rtt.png)

This graph plots RTT (x-axis) against achieved throughput in Mbps (y-axis), showing a downward curve as RTT increases. It demonstrates that TCP Reno becomes progressively less efficient at higher RTTs because the congestion window grows slower when ACKs take longer to return.

RTT vs Throughput Graph 1 RTT vs Throughput Graph 2

Congestion Window over Time Graph (cwnd_over_time.png)

At lower RTT the window climbs steeply and reaches a high steady state, while at higher RTT the growth is gradual and resets happen more frequently, keeping cwnd chronically low.

Cwnd over Time Graph 1 Cwnd over Time Graph 2

TraceMetrics Result for 10, 100 and 200 ms, Respectively

The trace metrics comparison illustrates that increasing RTT leads to reduced throughput, higher packet loss, and increased end-to-end delay due to slower congestion window growth and higher Bandwidth-Delay Product in TCP Reno.

TraceMetrics 10ms TraceMetrics 100ms TraceMetrics 200ms

Wireshark Analysis

The image below shows the TCP three-way handshake (SYN, SYN-ACK, ACK) followed by continuous data transmission between 10.1.1.1 (sender) and 10.1.1.2 (receiver), confirming successful connection establishment and active TCP Reno data flow.

Wireshark Handshake Trace

The image below displays Wireshark’s Expert Information, highlighting events such as duplicate ACKs, retransmissions, and out-of-order packets, which indicate congestion and TCP Reno’s loss recovery mechanisms.

Wireshark Expert Information

The graph below shows packet flow over time along with TCP errors, illustrating fluctuations in transmission rate and the occurrence of congestion-related issues such as retransmissions during the simulation.

Wireshark I/O Graph

Comments

Popular posts from this blog

How to Create Ubuntu 24.04 Bootable USB Using Rufus [Step-by-Step Guide]

How to Create Ubuntu 24.04 Bootable USB Using Rufus [Step-by-Step Guide] Are you planning to install or try Ubuntu 24.04 LTS ? The easiest and most reliable method is to create a bootable USB drive using Rufus on a Windows system. This detailed guide will help you create a Ubuntu 24.04 USB bootloader using Rufus with easy-to-follow steps and screenshots (optional). Here is the complete video of the bootloader creation and OS installation in Windows 11. 🧰 Requirements A USB flash drive (minimum 8GB recommended) A Windows PC Ubuntu 24.04 LTS ISO file Rufus USB creation tool 🧾 Steps to Create a Ubuntu 24.04 Bootable USB Using Rufus ✅ Step 1: Download Ubuntu 24.04 ISO Visit the official Ubuntu website and download the Ubuntu 24.04 LTS ISO file . ✅ Step 2: Download and Run Rufus Head to Rufus official site and download the latest version. Open the executable file (no installation required). ✅ Step 3: Insert USB Drive Plug in your USB drive. Rufus ...

Installing ns3 in Ubuntu 22.04 | Complete Instructions

In this post, we are going to see how to install ns-3.36.1 in Ubuntu 22.04. You can follow the video for complete details Tools used in this simulation: NS3 version ns-3.36.1  OS Used: Ubuntu 22.04 LTS Installation of NS3 (ns-3.36.1) There are some changes in the ns3 installation procedure and the dependencies. So open a terminal and issue the following commands Step 1:  Prerequisites $ sudo apt update In the following packages, all the required dependencies are taken care and you can install all these packages for the complete use of ns3. $ sudo apt install g++ python3 python3-dev pkg-config sqlite3 cmake python3-setuptools git qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools gir1.2-goocanvas-2.0 python3-gi python3-gi-cairo python3-pygraphviz gir1.2-gtk-3.0 ipython3 openmpi-bin openmpi-common openmpi-doc libopenmpi-dev autoconf cvs bzr unrar gsl-bin libgsl-dev libgslcblas0 wireshark tcpdump sqlite sqlite3 libsqlite3-dev  libxml2 libxml2-dev libc6-dev libc6-dev-i386 libc...

NS2 (NS-2.35) Installation in Ubuntu 11.10

This post will help you in installing Network Simulator 2 version NS2.35 in Ubuntu 11.10 Instructions Install Ubuntu Download NS-2.35 ( http://sourceforge.net/projects/nsnam/files/allinone/ns-allinone-2.35/ns-allinone-2.35.tar.gz/download ) Unzip or untar it to any folder (recommended is /home/ loginname) using the following commands one by one sudo apt-get update sudo apt-get install build-essential autoconf automake libxmu-dev tar zxvf ns-allinone-2.35.tar.gz cd ns-allinone-2.35 ./install Once installed the PATH information will be provided to you. Copy the PATH and LD_LIBRARY_PATH Variable to .bashrc (see a dot in the beginning) Input the path information in .bashrc file like this export PATH=$PATH:<Place your paths here> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: <place the LD_LIBRARY_PATHS> here. Once done, save the file and close execute the command source .bashrc try ns or nam to see whether your installation succeeded.