Impact of Channel Error Rate on Stop-and-Wait vs. Go-Back-N Efficiency
Performance Evaluation Over a Point-to-Point Link in NS-3
Theory Behind This Behaviour
Stop-and-Wait and Go-Back-N are flow control protocols that differ fundamentally in how they utilize the communication channel. In Stop-and-Wait, the sender transmits a single packet and remains idle until an acknowledgement (ACK) is received before sending the next packet. This mechanism incurs significant propagation and idle overhead, particularly when channel propagation delay or packet error rates increase, resulting in low throughput and poor channel efficiency.
In contrast, Go-Back-N (GBN) uses a sliding-window mechanism that enables multiple unacknowledged packets to be transmitted consecutively via pipelining. If an error or packet drop occurs, the receiver discards the corrupted packet along with all subsequent out-of-order packets, prompting the sender to retransmit the window starting from the lost sequence number. Although this policy can increase retransmission overhead, pipelined transmissions ensure substantially higher link utilization. While increasing channel error rates degrade throughput across both schemes, Stop-and-Wait exhibits a much steeper performance drop compared to Go-Back-N.
Simulation Source Code
#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/error-model.h"
#include "ns3/flow-monitor-module.h"
using namespace ns3;
NS_LOG_COMPONENT_DEFINE("StopWaitVsGBN");
int main(int argc, char *argv[])
{
double errorRate = 0.00001; // Vary this value for error experiments
uint32_t packetSize = 1024;
std::string dataRate = "5Mbps";
CommandLine cmd;
cmd.AddValue("errorRate", "Bit error rate", errorRate);
cmd.Parse(argc, argv);
NodeContainer nodes;
nodes.Create(2);
PointToPointHelper p2p;
p2p.SetDeviceAttribute("DataRate", StringValue(dataRate));
p2p.SetChannelAttribute("Delay", StringValue("2ms"));
NetDeviceContainer devices = p2p.Install(nodes);
// Error model configuration
Ptr<RateErrorModel> em = CreateObject<RateErrorModel>();
em->SetAttribute("ErrorRate", DoubleValue(errorRate));
devices.Get(1)->SetAttribute("ReceiveErrorModel", PointerValue(em));
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 = 8080;
// Receiver configuration
PacketSinkHelper sink("ns3::TcpSocketFactory",
InetSocketAddress(Ipv4Address::GetAny(), port));
ApplicationContainer sinkApp = sink.Install(nodes.Get(1));
sinkApp.Start(Seconds(0.0));
sinkApp.Stop(Seconds(20.0));
// Sender configuration
OnOffHelper client("ns3::TcpSocketFactory",
InetSocketAddress(interfaces.GetAddress(1), port));
client.SetAttribute("PacketSize", UintegerValue(packetSize));
client.SetAttribute("DataRate", StringValue("10Mbps"));
client.SetAttribute("OnTime", StringValue("ns3::ConstantRandomVariable[Constant=1]"));
client.SetAttribute("OffTime", StringValue("ns3::ConstantRandomVariable[Constant=0]"));
ApplicationContainer clientApp = client.Install(nodes.Get(0));
clientApp.Start(Seconds(1.0));
clientApp.Stop(Seconds(20.0));
// ---- SWITCH BETWEEN STOP-AND-WAIT AND GBN ----
// Stop-and-Wait (Buffer window limited to single segment)
Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(1024));
Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(1024));
// For Go-Back-N (Uncomment below and comment above to enlarge window buffer)
// Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(65535));
// Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(65535));
// Flow Monitor
FlowMonitorHelper flowmon;
Ptr<FlowMonitor> monitor = flowmon.InstallAll();
Simulator::Stop(Seconds(20.0));
Simulator::Run();
monitor->CheckForLostPackets();
Ptr<Ipv4FlowClassifier> classifier =
DynamicCast<Ipv4FlowClassifier>(flowmon.GetClassifier());
std::map<FlowId, FlowMonitor::FlowStats> stats = monitor->GetFlowStats();
for (auto &flow : stats)
{
double throughput = flow.second.rxBytes * 8.0 / 20.0 / 1024 / 1024;
std::cout << "Throughput: " << throughput << " Mbps\n";
std::cout << "Packet Loss: " << flow.second.lostPackets << "\n";
}
Simulator::Destroy();
return 0;
}
TraceMetrics Analysis
|
| TraceMetrics Metric Comparison |
Simulation Results & Output
|
|
| Terminal Output Metrics under Varying Error Rates |
Comparative Performance Graph
|
| Throughput vs. Error Rate Comparison Graph |
Packet Capture Analysis (Wireshark)
|
|
| Wireshark Packet Traces Showing Loss and Retransmissions |
Topology Visualization (NetAnim)
|
| NetAnim Animation Output |
Conclusion
The simulation demonstrates that Go-Back-N achieves significantly higher throughput than Stop-and-Wait due to its ability to continuously transmit data without halting for individual acknowledgments. Stop-and-Wait suffers from poor channel efficiency because the sender remains idle throughout the round-trip propagation interval, leading to rapid throughput collapse as error rates increase.
In Go-Back-N, while multiple packets must be retransmitted when an error occurs, overall performance remains resilient due to pipelining. Furthermore, when underlying TCP flows experience packet loss, TCP interprets packet drops as congestion signals and dynamically throttles its transmission rate via congestion window reductions. Overall, Go-Back-N provides superior link utilization across point-to-point networks, particularly under moderate error conditions.
Comments
Post a Comment