50-Node Ethernet LAN Simulation using CSMA - Measuring Average Collision Count vs. Packet Size
1.
Objective
The aim of this exercise is to simulate a 50-node Ethernet Local Area Network using the CSMA (Carrier Sense Multiple Access) protocol in NS-3 and quantitatively measure how the average number of collisions per node varies with packet size ranging from 64 bytes to 1500 bytes.
2.
Write-Up
2.1
Why CSMA and Why Collisions Happen
Think of a shared Ethernet LAN like a walkie-talkie channel shared
among 50 people. Everyone can hear everyone, but only one person can speak at a
time. If two people press 'talk' simultaneously, their voices collide and the
message is lost. CSMA tries to solve this by making each device listen before
transmitting, but when 49 nodes all sense silence at the same moment and
transmit together, collisions are unavoidable.
In NS-3, the CsmaNetDevice models this exactly. Every time a node
detects a collision and backs off, it fires a MacTxBackoff trace event — which
our simulation intercepts and counts. The exponential random back-off then
makes it wait a random interval before retrying, mimicking real 802.3 Ethernet
behaviour.
2.2
The Packet Size Effect — Why It Matters
Packet size has a compounding effect on collisions for a simple
reason: larger packets occupy the shared wire for longer. During that entire
duration, any other node that starts transmitting causes a collision. A 64-byte
packet is a quick message — it clears the channel fast. A 1500-byte packet is a
lengthy speech that keeps the channel busy, creating a much larger window for
simultaneous transmissions from other nodes.
With Node 0 hammering all 49 server nodes at 100 packets per
second each, the channel load is extreme --- this is intentional, to
stress-test the CSMA mechanism and amplify the collision effect across the full
packet size range.
However, under high network load, this relationship may become non-linear due to the influence of the CSMA backoff algorithm, which can reduce collisions at intermediate packet sizes.
2.3
Simulation Design
50 nodes are created on a single CSMA channel configured at 100
Mbps with a propagation delay of 6560 microseconds (matching the maximum
round-trip delay for a 100BASE-T segment). Node 0 acts
as the UDP Echo Client, sending packets to each of the 49 server nodes (Nodes
1–49). Each server node runs a UDP Echo Server on port 9. Six discrete packet
sizes are evaluated: 64, 128, 256, 512, 1024, and 1500 bytes. For each size,
the simulation runs for 2 simulated seconds. The NetAnim XML is generated
during the 64-byte run.
Collision Measurement Note:
The MacTxBackoff trace source is used as an approximation of collision events. This trace is triggered whenever a node defers or retransmits due to channel contention. While not every backoff corresponds to a direct collision, it closely reflects collision behavior in high-load shared CSMA environments.
3.
LLM Used and Prompt
LLM Used: Claude
(Anthropic) — Claude Sonnet 4.6
Prompt Given:
"I am a second-year B.Tech Computer Science student at VIT
Chennai. My CN lab assignment asks me to simulate a 50-node Ethernet LAN using
the CSMA protocol in NS-3 and measure how the average number of collisions per
node changes as packet size increases from 64 bytes to 1500 bytes. Please help
me write a complete NS-3 C++ simulation file runnable as ./ns3 run
scratch/24bps1102.cc. The simulation should create 50 nodes on a single CSMA
channel at 100 Mbps, use UDP Echo clients on all nodes sending to one server
node, vary packet size across 64, 128, 256, 512, 1024 and 1500 bytes, and track
collisions using the MacTxBackoff trace source. Also generate a Gnuplot script
for plotting average collisions vs packet size, and a NetAnim XML file."
4.
Source Code
#include "ns3/core-module.h" #include "ns3/network-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/netanim-module.h"
#include "ns3/gnuplot.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("CsmaCollisionSim");
uint32_t g_collisionCount = 0;
void CollisionCallback(std::string context, Ptr<const Packet> packet)
{
g_collisionCount++;
}
int main(int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse(argc, argv);
uint32_t numNodes = 50;
std::vector<uint32_t> packetSizes = {64, 128, 256, 512, 1024, 1500};
std::vector<double> avgCollisions;
Gnuplot2dDataset dataset;
dataset.SetTitle("Avg Collisions vs Packet Size");
dataset.SetStyle(Gnuplot2dDataset::LINES_POINTS);
for (uint32_t pktSize : packetSizes)
{
g_collisionCount = 0;
NodeContainer nodes;
nodes.Create(numNodes);
CsmaHelper csma;
csma.SetChannelAttribute("DataRate", StringValue("100Mbps"));
csma.SetChannelAttribute("Delay", TimeValue(MicroSeconds(6560)));
NetDeviceContainer devices = csma.Install(nodes);
InternetStackHelper internet;
internet.Install(nodes);
Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = ipv4.Assign(devices);
Config::Connect("/NodeList/*/DeviceList/*/$ns3::CsmaNetDevice/MacTxBackoff",
MakeCallback(&CollisionCallback));
uint16_t port = 9;
double simTime = 2.0;
for (uint32_t i = 1; i < numNodes; i++)
{
UdpEchoServerHelper echoServer(port);
ApplicationContainer serverApp = echoServer.Install(nodes.Get(i));
serverApp.Start(Seconds(0.0));
serverApp.Stop(Seconds(simTime));
UdpEchoClientHelper echoClient(interfaces.GetAddress(i), port);
echoClient.SetAttribute("MaxPackets", UintegerValue(200));
echoClient.SetAttribute("Interval", TimeValue(MilliSeconds(10)));
echoClient.SetAttribute("PacketSize", UintegerValue(pktSize));
ApplicationContainer clientApp = echoClient.Install(nodes.Get(0));
clientApp.Start(Seconds(0.1));
clientApp.Stop(Seconds(simTime));
}
if (pktSize == 64)
{
AnimationInterface anim("csma_animation.xml");
uint32_t row = 0, col = 0;
for (uint32_t i = 0; i < numNodes; i++)
{
anim.SetConstantPosition(nodes.Get(i), col * 20 + 10, row * 20 + 10);
col++;
if (col >= 10) { col = 0; row++; }
}
anim.EnablePacketMetadata(true);
Simulator::Run();
Simulator::Destroy();
}
else
{
Simulator::Run();
Simulator::Destroy();
}
double avgColl = (double)g_collisionCount / (numNodes - 1);
avgCollisions.push_back(avgColl);
dataset.Add(pktSize, avgColl);
std::cout << "PacketSize=" << pktSize
<< " TotalCollisions=" << g_collisionCount
<< " AvgCollisions=" << avgColl << std::endl;
}
Gnuplot plot("collision_vs_pktsize.png");
plot.SetTitle("50-Node CSMA LAN: Average Collisions vs Packet Size");
plot.SetTerminal("png");
plot.SetLegend("Packet Size (bytes)", "Average Collision Count per Node");
plot.AddDataset(dataset);
std::ofstream plotFile("collision_vs_pktsize.plt");
plot.GenerateOutput(plotFile);
plotFile.close();
system("gnuplot collision_vs_pktsize.plt");
std::cout << "\n=== Summary ===" << std::endl;
for (size_t i = 0; i < packetSizes.size(); i++)
{
std::cout << "Packet Size: " << packetSizes[i]
<< " bytes | Avg Collisions: " << avgCollisions[i] << std::endl;
}
return 0;
}
5.
Results — Collision Data
|
Packet Size (bytes) |
Total Collisions |
Avg Collisions / Node |
|
64 |
57,429 |
1172.0 |
|
128 |
61,893 |
1263.1 |
|
256 |
45,703 |
932.7 |
|
512 |
36,268 |
740.2 |
|
1024 |
26,498 |
540.8 |
|
1500 |
78,989 |
1612.0 |
6.
Graph — Average Collisions vs Packet Size
The graph plots
average collision count per node against packet size. The trend shows that
collisions are not strictly monotonic — they peak at 128 bytes, dip through
256–1024 bytes (back-off algorithm spreading retransmissions), then spike
dramatically at 1500 bytes. This non-linear behaviour is a real characteristic
of CSMA under heavy load and is more interesting than a simple straight line.
7.
NetAnim Animation
Figure 2: NetAnim shows all 50 nodes in a 10x5 grid connected to a shared CSMA bus. Node 0 (top-left) is the client. Animated packet flows from Node 0 fan out to all 49 server nodes simultaneously, visually demonstrating the congestion that causes high collision counts in this topology.
8.
Result Analysis
The simulation revealed an interesting non-monotonic collision
pattern rather than a simple linear increase. Key findings:
•
Collisions peak at 128 bytes (1263 avg) — not at the largest
packet size. This is because at this size, nodes transmit frequently enough
that the back-off algorithm hasn't yet introduced sufficient spacing between
retransmissions.
•
From 256 to 1024 bytes, collisions actually decrease. Larger
packets mean fewer total transmissions within the 2-second window, allowing the
exponential back-off to be more effective.
•
At 1500 bytes, collisions spike to their absolute maximum (1612
avg). At MTU size, the channel occupancy per packet is so long that even with
fewer transmissions, the probability of overlap is highest.
• Real-world implication: shared Ethernet under extreme load behaves non-intuitively. This is precisely why modern networks use switches (not hubs/buses) — to eliminate shared collision domains entirely.
9. Conclusion
This simulation demonstrates that collision behavior in a shared
CSMA Ethernet LAN is non-linear with respect to packet size. While very large
packets increase collisions due to longer channel occupancy, medium-sized
packets reduce collisions due to more effective backoff spacing. These results
highlight the importance of packet size selection and reinforce why modern
networks avoid shared collision domains by using switches.
Comments
Post a Comment