I am trying to simulate TCP traffic over a simple LTE network with EPC and one remote host. I have referred the lena-simple-epc.cc example from lte module, to setup a simplest LTE network, with single UE, single eNB, EPC and one remote Host.
The aim of this setup is to run TCP application over the network and observe the maximum datarate that can be obtained (Which should ideally be <= Bottleneck Bandwidth of the Network).
I have configured the eNB DL and UL bandwidth both to be 100 as shown below.
When I run a TCP application with PacketSinkHelper(TcpSocket) and BulkSendHelper(TcpSocket), we observe the throughput for both DL and UL to 4.3 Mbps and 4.2 Mbps respectively.However, when I use a UdpClientHelper and set the data rate to 120 Mbps , I observe the Throughput to be around 72 to 73 Mbps for both DL and UL.Â
Well, my query to the community is why we observe TCP traffic to get clamped at 4-5 Mbps, when we have much more bandwidth available (verified by UDP traffic achieving 72 Mbps), should not it consume the entire bandwidth? Is any configuration missing on the EPC or LTE stack which can clamp TCP traffic to 5 Mbps? Â Any help in this regard will be highly appreciated.Â
#include "ns3/applications-module.h"
#include "ns3/config-store-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/lte-module.h"
#include "ns3/mobility-module.h"
#include "ns3/point-to-point-module.h"
using namespace ns3;
/**
* Sample simulation script for LTE+EPC. It instantiates several eNodeBs,
* attaches one UE per eNodeB starts a flow for each UE to and from a remote host.
* It also starts another flow between each UE pair.
*/
NS_LOG_COMPONENT_DEFINE("LenaSimpleEpc");
Ptr<PacketSink> sinkDL;
Ptr<PacketSink> sinkUL;
double last_rx_bytes_dl = 0;
double last_rx_bytes_ul = 0;
void
GetThroughput() {
Time now = Simulator::Now ();
double cur = (sinkDL->GetTotalRx() - last_rx_bytes_dl) * (double) 8 / 1e6;
std::cout << now.GetSeconds() << "s: Throughput DL : " << cur << "Mbits/s" << std::endl;
last_rx_bytes_dl = sinkDL->GetTotalRx ();
cur = (sinkUL->GetTotalRx() - last_rx_bytes_ul) * (double) 8 / 1e6;
std::cout << now.GetSeconds() << "s: Throughput UL : " << cur << "Mbits/s" << std::endl;
last_rx_bytes_ul = sinkUL->GetTotalRx ();
Simulator::Schedule(Seconds(1), &GetThroughput);
}
int
main(int argc, char* argv[])
{
uint16_t numEnb = 1;
uint16_t numUe = 1;
Time simTime = Seconds(60);
Time interPacketInterval = MicroSeconds(100);
bool disableDl = false;
bool disableUl = false;
bool disableTcp = false;
// Command line arguments
CommandLine cmd;
cmd.AddValue("numNEnb", "Number of eNodeBs", numEnb);
cmd.AddValue("numUe", "Number of UEs", numUe);
cmd.AddValue("simTime", "Total duration of the simulation", simTime);
cmd.AddValue("interPacketInterval", "Inter packet interval", interPacketInterval);
cmd.AddValue("disableDl", "Disable downlink data flows", disableDl);
cmd.AddValue("disableUl", "Disable uplink data flows", disableUl);
cmd.Parse(argc, argv);
Ptr<LteHelper> lteHelper = CreateObject<LteHelper>();
Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper>();
lteHelper->SetEpcHelper(epcHelper);
lteHelper->SetEnbDeviceAttribute("DlBandwidth", UintegerValue(100));
lteHelper->SetEnbDeviceAttribute("UlBandwidth", UintegerValue(100));
Ptr<Node> pgw = epcHelper->GetPgwNode();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create(1);
Ptr<Node> remoteHost = remoteHostContainer.Get(0);
InternetStackHelper internet;
internet.Install(remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute("DataRate", DataRateValue(DataRate("100Gb/s")));
p2ph.SetDeviceAttribute("Mtu", UintegerValue(1500));
p2ph.SetChannelAttribute("Delay", TimeValue(MicroSeconds(10)));
NetDeviceContainer internetDevices = p2ph.Install(pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign(internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress(1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting =
ipv4RoutingHelper.GetStaticRouting(remoteHost->GetObject<Ipv4>());
remoteHostStaticRouting->AddNetworkRouteTo(Ipv4Address("7.0.0.0"), Ipv4Mask("255.0.0.0"), 1);
NodeContainer ueNodes;
NodeContainer enbNodes;
enbNodes.Create(numEnb);
ueNodes.Create(numUe);
// Install Mobility Model
MobilityHelper mobility;
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
Ptr<ListPositionAllocator> positionAllocEnb = CreateObject<ListPositionAllocator>();
for (uint16_t i = 0; i < numEnb; i++)
{
positionAllocEnb->Add(Vector(0, 0, 0));
}
mobility.SetPositionAllocator(positionAllocEnb);
mobility.Install(enbNodes);
Ptr<ListPositionAllocator> positionAllocUe = CreateObject<ListPositionAllocator>();
for (uint16_t i = 0; i < numUe; i++)
{
positionAllocUe->Add(Vector(0, 0, 0));
}
mobility.SetPositionAllocator(positionAllocUe);
mobility.Install(ueNodes);
// Install LTE Devices to the nodes
NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice(enbNodes);
NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice(ueNodes);
// Install the IP stack on the UEs
internet.Install(ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address(NetDeviceContainer(ueLteDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
{
Ptr<Node> ueNode = ueNodes.Get(u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting =
ipv4RoutingHelper.GetStaticRouting(ueNode->GetObject<Ipv4>());
ueStaticRouting->SetDefaultRoute(epcHelper->GetUeDefaultGatewayAddress(), 1);
}
// Attach one UE per eNodeB
for (uint16_t i = 0; i < numUe; i++)
{
uint16_t enbIndex = (i < enbNodes.GetN()) ? i : 0;
lteHelper->Attach(ueLteDevs.Get(i), enbLteDevs.Get(enbIndex));
// side effect: the default EPS bearer will be activated
}
// Install and start applications on UEs and remote host
uint16_t dlPort = 1100;
uint16_t ulPort = 2000;
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN(); ++u)
{
if (!disableDl)
{
if(!disableTcp)
{
std::cout<<"Setting TCP Traffic"<<std::endl;
PacketSinkHelper dlPacketSinkHelper("ns3::TcpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), dlPort));
serverApps.Add(dlPacketSinkHelper.Install(ueNodes.Get(u)));
BulkSendHelper dlClient("ns3::TcpSocketFactory", InetSocketAddress(ueIpIface.GetAddress(u), dlPort));
clientApps.Add(dlClient.Install(remoteHost));
sinkDL = StaticCast<PacketSink> (serverApps.Get (0));
}
else
{
std::cout<<"Setting UDP Traffic"<<std::endl;
PacketSinkHelper dlPacketSinkHelper("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), dlPort));
serverApps.Add(dlPacketSinkHelper.Install(ueNodes.Get(u)));
UdpClientHelper dlClient(ueIpIface.GetAddress(u), dlPort);
dlClient.SetAttribute("Interval", TimeValue(interPacketInterval));
dlClient.SetAttribute("MaxPackets", UintegerValue(1000000));
clientApps.Add(dlClient.Install(remoteHost));
sinkDL = StaticCast<PacketSink> (serverApps.Get (0));
}
dlPort++;
}
if (!disableUl)
{
if(!disableTcp)
{
std::cout<<"Setting TCP Traffic"<<std::endl;
PacketSinkHelper ulPacketSinkHelper("ns3::TcpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), ulPort));
serverApps.Add(ulPacketSinkHelper.Install(remoteHost));
BulkSendHelper ulClient("ns3::TcpSocketFactory", InetSocketAddress(remoteHostAddr, ulPort));
clientApps.Add(ulClient.Install(ueNodes.Get(u)));
sinkUL = StaticCast<PacketSink> (serverApps.Get (1));
}
else
{
std::cout<<"Setting UDP Traffic"<<std::endl;
PacketSinkHelper ulPacketSinkHelper("ns3::UdpSocketFactory", InetSocketAddress(Ipv4Address::GetAny(), ulPort));
serverApps.Add(ulPacketSinkHelper.Install(remoteHost));
UdpClientHelper ulClient(remoteHostAddr, ulPort);
ulClient.SetAttribute("Interval", TimeValue(interPacketInterval));
ulClient.SetAttribute("MaxPackets", UintegerValue(1000000));
clientApps.Add(ulClient.Install(ueNodes.Get(u)));
sinkUL = StaticCast<PacketSink> (serverApps.Get (1));
}
ulPort++;
}
}
serverApps.Start(Seconds(1));
clientApps.Start(Seconds(2));
serverApps.Stop(simTime);
clientApps.Stop(simTime);
// lteHelper->EnableTraces();
// Uncomment to enable PCAP tracing
// p2ph.EnablePcapAll("lena-simple-epc");
Simulator::Schedule(Seconds(1), &GetThroughput);
Simulator::Stop(simTime);
Simulator::Run();
/*GtkConfigStore config;
config.ConfigureAttributes();*/
Simulator::Destroy();
return 0;
}