Skip to main content

50-Node Ethernet LAN Simulation using CSMA | NS3 Project 12

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

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.