Simulate Multiple Concurrent FTP Sessions and Analyze Aggregate Throughput
Simulation Environment: ns-3 | Tools Used: FlowMonitor, NetAnim, TraceMetrics
1. Objective
The primary objective of this experiment is to simulate a network scenario in which multiple concurrent File Transfer Protocol (FTP)-like sessions operate simultaneously over a shared network infrastructure. Using the ns-3 discrete-event network simulator, the study models seven independent TCP bulk-send flows that traverse a common bottleneck link. The experiment aims to measure and analyze the individual throughput of each flow as well as the aggregate throughput delivered to the single receiver node. By configuring access links with high capacity and constraining the router-to-receiver link to a narrow bandwidth, the simulation deliberately induces congestion to study how TCP's congestion control mechanisms influence flow behavior, resource sharing, and overall network efficiency.
Furthermore, the experiment evaluates fairness among competing flows, particularly in light of staggered flow start times, and investigates how late-arriving flows behave in a congested environment relative to established flows. The findings are intended to provide practical insight into the dynamics of TCP traffic under real-world-like conditions, offering a foundation for understanding congestion, queuing behaviour, and bandwidth allocation in modern packet-switched networks.
2. Network Topology
The network topology used in this simulation is a dumbbell topology, which is a widely adopted architecture in congestion analysis studies. The topology consists of nine nodes in total: seven sender nodes (S0 through S6), one intermediate router node (R), and one receiver node (D). Each sender is connected to the router through a dedicated access link, while the router is connected to the receiver through a single bottleneck link.
The access links are configured as high-speed point-to-point links with a data rate of 10 Mbps and a propagation delay of 2 ms. These links comfortably support the traffic generated by individual senders, ensuring that congestion does not occur at the ingress side of the router. The bottleneck link, connecting the router to the receiver, is intentionally constrained to 2 Mbps with a propagation delay of 20 ms. Since the aggregate traffic entering the router from all seven senders can potentially reach up to 70 Mbps, the bottleneck link becomes heavily congested, serving as the critical chokepoint of the topology.
This design choice is deliberate: the bottleneck link allows the simulation to study the effects of TCP congestion control, fair bandwidth allocation, and queue management under realistic stress conditions. All communication in this topology follows TCP semantics, making the simulation suitable for analyzing how multiple concurrent FTP-like sessions compete for a shared resource.
S0–S6 ──(10Mbps/2ms)──> Router ──(2Mbps/20ms)──> Receiver
3. Simulation Setup and Tools Used
The simulation was implemented using the ns-3 (Network Simulator 3) framework, a widely used open-source discrete-event network simulator designed for research and educational purposes. ns-3 provides accurate models of TCP/IP protocol stacks, network devices, and channel characteristics, making it suitable for replicating real-world network behavior.
Link Configuration:
All links are implemented as point-to-point (P2P) connections. The seven access links (sender to router) each operate at 10 Mbps with a propagation delay of 2 ms. The single bottleneck link (router to receiver) operates at 2 Mbps with a propagation delay of 20 ms, creating a realistic asymmetry between ingress and egress capacity at the router.
Application Model:
FTP-like traffic is modeled using the ns-3 BulkSendHelper, which continuously transmits data over TCP without any application-level pauses or limits (MaxBytes = 0). At the receiver end, PacketSinkHelper applications are installed to accept and absorb incoming TCP connections on individual ports beginning from port 5000. This ensures that each sender-receiver pair maintains a distinct TCP connection throughout the simulation.
Staggered Start Times:
To simulate realistic arrival patterns and to study how established flows respond to new competing flows, each sender is assigned a unique start time: Sender 0 begins at t = 1 s, Sender 1 at t = 2 s, and so on up to Sender 6 at t = 7 s. The total simulation duration is 20 seconds, providing sufficient time for all flows to reach steady-state behavior.
Tracing and Monitoring:
ASCII trace files (access.tr, bottleneck.tr) and PCAP captures are enabled on all links to provide detailed packet-level logs. These files serve as inputs to the TraceMetrics tool for post-simulation analysis. The FlowMonitor module (available as commented code) can be enabled to collect per-flow statistics including bytes received, packet loss, and mean delay.
Tools Used:
ns-3: Core simulation engine for modeling the network topology, protocols, and applications. FlowMonitor: ns-3 module for per-flow performance metrics. TraceMetrics: External GUI-based tool for parsing .tr trace files and generating throughput graphs. NetAnim: XML-based animation tool for visualizing packet flow across the topology.
4. Source Code
The following C++ source code implements the described simulation in ns-3. The program creates the dumbbell topology, installs TCP BulkSend applications on each sender node with staggered start times, and enables both ASCII and PCAP trace output for analysis. NetAnim XML output is also generated for visualization purposes.
File: 24bps1070.cc
#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/flow-monitor-module.h"
#include "ns3/trace-helper.h"
#include "ns3/netanim-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("MultiFtpExample");
int main() {
uint32_t nFlows = 7;
double simTime = 20.0;
NodeContainer senders; senders.Create(nFlows);
NodeContainer router; router.Create(1);
NodeContainer receiver; receiver.Create(1);
InternetStackHelper stack;
stack.InstallAll();
// Access links (fast)
PointToPointHelper access;
access.SetDeviceAttribute("DataRate", StringValue("10Mbps"));
access.SetChannelAttribute("Delay", StringValue("2ms"));
// Bottleneck link (slow)
PointToPointHelper bottleneck;
bottleneck.SetDeviceAttribute("DataRate", StringValue("2Mbps"));
bottleneck.SetChannelAttribute("Delay", StringValue("20ms"));
Ipv4AddressHelper address;
std::vector<Ipv4InterfaceContainer> senderIfs;
for (uint32_t i = 0; i < nFlows; i++) {
NodeContainer pair(senders.Get(i), router.Get(0));
NetDeviceContainer dev = access.Install(pair);
std::ostringstream subnet;
subnet << "10.1." << i+1 << ".0";
address.SetBase(subnet.str().c_str(), "255.255.255.0");
senderIfs.push_back(address.Assign(dev));
}
NodeContainer rr(router.Get(0), receiver.Get(0));
NetDeviceContainer devRR = bottleneck.Install(rr);
address.SetBase("10.2.0.0", "255.255.255.0");
Ipv4InterfaceContainer rrIf = address.Assign(devRR);
AsciiTraceHelper ascii;
access.EnableAsciiAll(ascii.CreateFileStream("access.tr"));
bottleneck.EnableAsciiAll(ascii.CreateFileStream("bottleneck.tr"));
access.EnablePcapAll("access");
bottleneck.EnablePcapAll("bottleneck");
Ipv4GlobalRoutingHelper::PopulateRoutingTables();
uint16_t basePort = 5000;
ApplicationContainer sinkApps;
for (uint32_t i = 0; i < nFlows; i++) {
PacketSinkHelper sink("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), basePort + i));
sinkApps.Add(sink.Install(receiver.Get(0)));
}
sinkApps.Start(Seconds(0.0)); sinkApps.Stop(Seconds(simTime));
for (uint32_t i = 0; i < nFlows; i++) {
BulkSendHelper source("ns3::TcpSocketFactory",
InetSocketAddress(rrIf.GetAddress(1), basePort + i));
source.SetAttribute("MaxBytes", UintegerValue(0));
ApplicationContainer srcApp = source.Install(senders.Get(i));
srcApp.Start(Seconds(1.0 + i));
srcApp.Stop(Seconds(simTime));
}
Simulator::Stop(Seconds(simTime));
//NetAnim Code : (Either Flow Monitor or NetAnim should be uncommented to get the OUTPUT)
//AnimationInterface anim("multi-ftp.xml");
//for (uint32_t i = 0; i < nFlows; i++)
//anim.SetConstantPosition(senders.Get(i), 0.0, i * 20.0);
//anim.SetConstantPosition(router.Get(0), 50.0, 50.0);
//anim.SetConstantPosition(receiver.Get(0), 100.0, 50.0);
monitor->CheckForLostPackets();
Save FlowMonitor results to XML
monitor->SerializeToXmlFile("flowmon.xml", true, true);
Ptr<Ipv4FlowClassifier> classifier =
DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats();
std::ofstream outFile("throughput.dat");
totalThroughput = 0;
for (auto &flow : stats) {
Ipv4FlowClassifier::FiveTuple t = classifier->FindFlow(flow.first);
double throughput = flow.second.rxBytes * 8.0 /
(simTime * 1000000.0);
totalThroughput += throughput;
outFile << flow.first << " " << throughput << std::endl;
std::cout << "Flow " << flow.first
<< " (" << t.sourceAddress << " -> " << t.destinationAddress << ")\n";
std::cout << " Throughput: " << throughput << " Mbps\n";
}
std::cout << "Aggregate Throughput: "
<< totalThroughput << " Mbps\n";
outFile.close();
Simulator::Run();
Simulator::Destroy();
}
5. Results and Graphs
5.1 Flow Monitor an Aggregate Throughput
5.2 Throughput Graph
The throughput graph, generated using TraceMetrics from the bottleneck.tr trace file, illustrates the time-varying throughput at the bottleneck link over the 20-second simulation. Each new flow entering the network causes a visible perturbation in the throughput profile of existing flows as TCP congestion control mechanisms negotiate bandwidth allocation. The graph shows an initial high-throughput phase for the first sender, followed by progressive reduction as additional flows join and share the bottleneck capacity.
5.3 NetAnim Visualization
The NetAnim visualization, generated from the multi-ftp.xml output file, provides a graphical representation of the network topology and packet movement during simulation. Sender nodes are vertically arranged on the left, the router is positioned at the center, and the receiver is placed on the right. Animated packets traveling along each link confirm that all seven TCP flows are active and successfully routing through the router toward the receiver. The animation also visually demonstrates congestion buildup at the bottleneck link as the simulation progresses.
5.4 Throughput Data (throughput.dat)
The throughput.dat file records throughput values for each flow identified by the FlowMonitor module. Due to the bidirectional nature of TCP, even-numbered flow IDs correspond to reverse ACK flows while odd-numbered IDs represent forward data flows. The table below presents the recorded data along with flow direction classification:
Flow ID | Throughput (Mbps) | Direction |
1 | 0.5088370 | Data (BulkSend) |
2 | 0.0371472 | ACK/Control |
3 | 0.3250900 | Data (BulkSend) |
4 | 0.0244176 | ACK/Control |
5 | 0.2281870 | Data (BulkSend) |
6 | 0.0173952 | ACK/Control |
7 | 0.2366540 | Data (BulkSend) |
8 | 0.0180512 | ACK/Control |
9 | 0.2103120 | Data (BulkSend) |
10 | 0.0148272 | ACK/Control |
11 | 0.1696220 | Data (BulkSend) |
12 | 0.0104800 | ACK/Control |
13 | 0.2053730 | Data (BulkSend) |
14 | 0.0151568 | ACK/Control |
The aggregate throughput of all forward (data) flows is approximately 1.884 Mbps, which approaches the theoretical maximum of 2 Mbps on the bottleneck link, indicating high link utilization. The sum of ACK flows (approximately 0.135 Mbps) represents control traffic overhead inherent to TCP operation.
5.5 TraceMetrics Output
TraceMetrics was used to parse the bottleneck.tr and access.tr ASCII trace files produced by the simulation. The tool provides detailed statistics including packet transmission events, queue drop events, throughput timelines, and delay histograms. The trace output confirms the occurrence of packet drops at the router queue, particularly during the period when all seven flows are simultaneously active (after t = 7 s), validating the congestion scenario designed into the topology.
6.Results Analysis
Individual Flow Throughput. The data from throughput.dat reveals a clear disparity in per-flow throughput. Flow 1 (the first sender, active from t = 1 s) achieves the highest throughput of approximately 0.509 Mbps, having been the sole occupant of the bottleneck link for one second before any competing flow arrived. Subsequent flows exhibit progressively lower throughput as each arrives into an increasingly congested network. Flow 11, representing the sixth sender (starting at t = 6 s), achieves only 0.170 Mbps, while the last-starting flow (Flow 13) recovers slightly to 0.205 Mbps as TCP's AIMD (Additive Increase, Multiplicative Decrease) mechanisms redistribute bandwidth over time.
Aggregate Throughput. The sum of all forward data flows (Flows 1, 3, 5, 7, 9, 11, and 13) yields a total aggregate throughput of approximately 1.884 Mbps out of a theoretical maximum of 2.0 Mbps on the bottleneck link. This represents a link utilization of approximately 94.2%, indicating that TCP is effectively saturating the available bandwidth despite its congestion avoidance mechanisms.
Impact of the Bottleneck Link. The bottleneck link is the single most important factor governing throughput in this topology. Since the aggregate offered load (up to 70 Mbps from seven 10 Mbps senders) vastly exceeds the bottleneck capacity (2 Mbps), the router's output queue experiences persistent congestion. Packet drops trigger TCP's congestion window reduction, causing all flows to reduce their sending rates. The resulting throughput profile is a direct consequence of TCP's collective response to queue overflow at the router's egress interface.
Fairness Analysis. The simulation reveals moderate unfairness among competing flows. Early-starting flows consistently achieve higher throughput than later-arriving flows because they establish larger congestion windows before encountering competition. The throughput difference between Flow 1 (0.509 Mbps) and Flow 11 (0.170 Mbps) illustrates this startup advantage. However, as the simulation approaches steady state, the TCP AIMD mechanism does progressively equalize bandwidth allocation, as evidenced by the relatively comparable throughput values among flows active for similar durations.
Effect of Staggered Start Times. Staggered start times introduce temporal unfairness that persists for several seconds after each new flow joins. Each newly starting flow initially encounters a congested network and must grow its congestion window from a minimal initial value, disadvantaging it relative to flows that have been running longer. Furthermore, each new flow entry causes a temporary throughput reduction in all existing flows as TCP reacts to increased packet loss rates, before recovering to a new shared equilibrium.
7. LLMs and Prompt Used
LLM Used: ChatGPT (OpenAI)
Prompt Used:
I want to simulate Multiple Concurrent FTP Sessions(atleast 7) using ns3.Help me build a versatile code to simulate any number of ftp sessions and analyze the throughput anf flow using tracemetrics and flowmonitor.Teach me the underlying concepts to this simulation and how the code works.
8. Interpretation and Conclusion
Key Observations. This simulation demonstrates several fundamental properties of TCP behavior under congestion. First, the bottleneck link is effectively saturated by seven competing TCP flows, achieving approximately 94% utilization. Second, the staggered start times create an inherent throughput hierarchy, with earlier-starting flows maintaining a persistent advantage over later arrivals. Third, the TCP congestion control mechanism distributes bandwidth in a broadly cooperative manner, though not with perfect fairness. Fourth, ACK traffic constitutes a small but measurable overhead, accounting for roughly 7% of total traffic volume across all flows.
Bandwidth Sharing. Bandwidth was shared among the seven flows in an approximately proportional manner, with differences attributable to start time advantages rather than protocol misbehavior. The TCP Reno congestion control algorithm, which is the default in ns-3, employs AIMD to achieve long-run fairness. The observed throughput values confirm that, given sufficient simulation time, flows do converge toward a more equitable distribution, though perfect max-min fairness is not achieved within the 20-second window.
Impact of Congestion. Congestion at the bottleneck link directly reduces the throughput of all competing flows. The progressive reduction in per-flow throughput as additional senders join the network underscores the sensitivity of TCP to bottleneck saturation. Queue drops at the router are the primary mechanism by which TCP receives congestion signals, triggering window reductions that ultimately limit aggregate throughput to slightly below the physical link capacity.
Real-World Relevance. The dumbbell topology with a bottleneck link closely models real-world scenarios such as ISP access networks, last-mile connections, and data center uplinks where multiple users or applications compete for a shared, constrained outbound link. The findings are directly applicable to the design and dimensioning of such networks, particularly in determining the number of concurrent sessions that can be supported while maintaining acceptable quality of service.
Conclusion. This experiment successfully simulates seven concurrent FTP-like TCP sessions over a dumbbell network topology in ns-3. The bottleneck link constrains aggregate throughput to approximately 1.884 Mbps, representing 94.2% utilization of the 2 Mbps capacity. Individual flow throughput varies from 0.170 Mbps to 0.509 Mbps, reflecting the influence of staggered start times and TCP congestion dynamics. While bandwidth sharing is not perfectly equitable, TCP's AIMD mechanism ensures cooperative sharing without complete flow starvation. The simulation validates the theoretical understanding of TCP congestion control and provides a practical foundation for analyzing multi-flow network performance in constrained environments.
Comments
Post a Comment