Get tcp throughput on ns3

 I trace the tcp data out at the sender side. And the throughput is printed out every 100ms.
tcpthroughout.cc

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation;
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#include <iostream>
#include <fstream>
#include <string>
#include<stdio.h>
#include<unistd.h>
#include "ns3/core-module.h"
#include "ns3/applications-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/traffic-control-module.h"
#include <vector>
using namespace ns3;
using namespace std;
NS_LOG_COMPONENT_DEFINE ("TCP-THROUGHPUT");
void GetNodeAddress(Ptr<Node>node,std::vector<Ipv4Address>&addresses)
{
    uint32_t interface=0;
    uint32_t totalInterface=0;
    Ptr<Ipv4> ipv4 =node->GetObject<Ipv4> ();
    totalInterface=ipv4->GetNInterfaces();
    for(interface=0;interface<totalInterface;interface++)
    {
        Ipv4Address srcIp = ipv4->GetAddress (interface, 0).GetLocal ();
        if(srcIp==Ipv4Address::GetLoopback()) continue;
        addresses.push_back(srcIp);
    }
}
class Throughput{
public:
    Throughput(){}
    ~Throughput(){}
    void IncomingData(uint32_t byte)
    {
    m_byte+=byte;
    if(m_first)
    {
        m_first=false;
        m_lastTime=Simulator::Now().GetMilliSeconds();
        Start();
    }
    }
    void CompulateRate()
    {
    float kbps=0.0;
    uint64_t now=Simulator::Now().GetMilliSeconds();
    uint32_t delta=now-m_lastTime;
        double time=Simulator::Now().GetSeconds();
    if(m_rateTimer.IsExpired())
    {
        kbps=m_byte*8/delta;
        m_byte=0;
        m_lastTime=now;
        NS_LOG_INFO(time<<" rate kbps "<<kbps);
            Time next=MilliSeconds(m_gap);
            m_rateTimer=Simulator::Schedule(next,&Throughput::CompulateRate,this);  
    }       
    }
    void Start()
    {
    Time next=MilliSeconds(m_gap);
    m_rateTimer=Simulator::Schedule(next,&Throughput::CompulateRate,this);      
    }
    void Stop()
    {
    m_rateTimer.Cancel();
    }
private:
    uint64_t m_byte{0};
    uint64_t m_lastTime;
    EventId m_rateTimer;
    uint32_t m_gap{100};
    bool m_first{true};
};

static const uint32_t totalTxBytes = 2000000000;
static uint32_t currentTxBytes = 0;

static const uint32_t writeSize = 1040;
static const double simDuration    = 200.0;
uint8_t data[writeSize];
static fstream mTcpWindowFile;


void StartFlow (Ptr<Socket>, Ipv4Address, uint16_t);
void WriteUntilBufferFull (Ptr<Socket>, uint32_t);

void OpenCwndTraceFile(std::string filename);
void CloseTcpWindowTraceFile();
void TcpWindowTrace(uint32_t oldval, uint32_t newval);
static void 
CwndTracer (uint32_t oldval, uint32_t newval)
{
    TcpWindowTrace(oldval,newval);
}
void OpenCwndTraceFile(std::string filename)
{

    char buf[FILENAME_MAX];
    string path = string (getcwd(buf, FILENAME_MAX)) + "/traces/" + filename;
    mTcpWindowFile.open(path.c_str(), fstream::out);

    sprintf (buf,  "%16s %16s",
            "Time", "Window");

    NS_ASSERT_MSG (mTcpWindowFile.is_open(), "No trace file to write to");
    mTcpWindowFile << buf << std::endl;
}
void CloseTcpWindowTraceFile()
{
    if (mTcpWindowFile.is_open())
        mTcpWindowFile.close();
    else
        NS_LOG_ERROR("Open file not found");
}
void TcpWindowTrace(uint32_t oldval, uint32_t newval)
{
    char line [255];
    oldval=oldval;
    sprintf (line, "%16f %16f",
            Simulator::Now().GetSeconds(),(double)newval/1460.0);

    NS_ASSERT_MSG (mTcpWindowFile.is_open(), "No trace file to write to");
    mTcpWindowFile << line << std::endl;
}
void RxDrop(Ptr<const Packet>p)
{
    Ptr<Packet> packet=p->Copy(); 
        PppHeader ppp;
          packet->RemoveHeader(ppp);
         Ipv4Header ipHeader;
         packet->RemoveHeader (ipHeader);
        if(packet->GetSize()>500)
        {
          TcpHeader header;
    packet->RemoveHeader(header);
    NS_LOG_INFO(Simulator::Now().GetSeconds()<<" drop packet "<<header.GetSequenceNumber()<<" source port "<<header.GetSourcePort ()<<" dest port "<<header.GetDestinationPort ());              
        }
}
void CwndDropProperty(SequenceNumber32 ack,int64_t rtt,int64_t rtt_var)
{
    NS_LOG_INFO("ack "<<ack<<" "<<rtt<<" "<<rtt_var);
}
static Throughput throughput;
void RxTrace(Ptr<const Packet>packet, const TcpHeader&header,
                 Ptr<const TcpSocketBase>socketbase)
{
    uint32_t size=packet->GetSize();
        float now=Simulator::Now().GetSeconds();
    throughput.IncomingData(size);
}
const uint32_t TOPO_DEFAULT_BW     = 2000000;    // in bps: 1Mbps
const uint32_t TOPO_DEFAULT_PDELAY =      100;    // in ms:   50ms
const uint32_t TOPO_DEFAULT_QDELAY =     300;    // in ms:  300ms
const uint32_t DEFAULT_PACKET_SIZE = 1000;
static NodeContainer BuildExampleTopo (uint64_t bps,
                                       uint32_t msDelay,
                                       uint32_t msQdelay)
{
    NodeContainer nodes;
    nodes.Create (2);

    PointToPointHelper pointToPoint;
    pointToPoint.SetDeviceAttribute ("DataRate", DataRateValue  (DataRate (bps)));
    pointToPoint.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (msDelay)));
    auto bufSize = std::max<uint32_t> (DEFAULT_PACKET_SIZE, bps * msQdelay / 8000);
    pointToPoint.SetQueue ("ns3::DropTailQueue",
                           "Mode", StringValue ("QUEUE_MODE_BYTES"),
                           "MaxBytes", UintegerValue (bufSize));
    NetDeviceContainer devices = pointToPoint.Install (nodes);

    InternetStackHelper stack;
    stack.Install (nodes);
    Ipv4AddressHelper address;
    address.SetBase ("10.1.1.0", "255.255.255.0");
    address.Assign (devices);

    // Uncomment to capture simulated traffic
    // pointToPoint.EnablePcapAll ("rmcat-example");

    // disable tc for now, some bug in ns3 causes extra delay
    TrafficControlHelper tch;
    tch.Uninstall (devices);

    return nodes;
}
static uint16_t servPort=5432;
int main (int argc, char *argv[])
{
    LogComponentEnable("TCP-THROUGHPUT", LOG_LEVEL_ALL);
    CommandLine cmd;
    cmd.Parse (argc, argv);
  for(int i = 0; i < writeSize; ++i)
    {
      char m = toascii (97 + i % 26);
      data[i] = m;
    }
    const uint64_t linkBw   = TOPO_DEFAULT_BW;
    const uint32_t msDelay  = TOPO_DEFAULT_PDELAY;
    const uint32_t msQDelay = TOPO_DEFAULT_QDELAY;
    NodeContainer n0n1 = BuildExampleTopo (linkBw, msDelay, msQDelay);
    std::vector<Ipv4Address>  servAddress;
    GetNodeAddress(n0n1.Get(1),servAddress);
        Ipv4Address addr;
    for(int i=0;i<servAddress.size();i++)
    {
        addr=servAddress[i];
    }
  PacketSinkHelper sink ("ns3::TcpSocketFactory",
                         InetSocketAddress (Ipv4Address::GetAny (), servPort));

  ApplicationContainer apps = sink.Install (n0n1.Get (1));
  apps.Start (Seconds (0.0));
  apps.Stop (Seconds (simDuration));
  Ptr<Socket> localSocket =
    Socket::CreateSocket (n0n1.Get (0), TcpSocketFactory::GetTypeId ());
  localSocket->Bind ();
  //localSocket->SetAttribute("SegmentSize",UintegerValue(1460));
  TcpSocketBase *base=static_cast<TcpSocketBase*>(PeekPointer(localSocket));
  base->TraceConnectWithoutContext("Tx", MakeCallback (&RxTrace));
  Simulator::ScheduleNow (&StartFlow, localSocket,
                          addr, servPort);
  Simulator::Stop (Seconds (simDuration+10.0));
  Simulator::Run ();
  localSocket->Close ();
  CloseTcpWindowTraceFile();
  Simulator::Destroy ();
  return 0;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//begin implementation of sending "Application"
void StartFlow (Ptr<Socket> localSocket,
                Ipv4Address servAddress,
                uint16_t servPort)
{
  NS_LOG_LOGIC ("Starting flow at time " <<  Simulator::Now ().GetSeconds ());
  localSocket->Connect (InetSocketAddress (servAddress, servPort)); //connect

  // tell the tcp implementation to call WriteUntilBufferFull again
  // if we blocked and new tx buffer space becomes available
  localSocket->SetSendCallback (MakeCallback (&WriteUntilBufferFull));
  WriteUntilBufferFull (localSocket, localSocket->GetTxAvailable ());
}
static uint32_t writecount=0;
void WriteUntilBufferFull (Ptr<Socket> localSocket, uint32_t txSpace)
{
  while (currentTxBytes < totalTxBytes && localSocket->GetTxAvailable () > 0) 
    {
      uint32_t left = totalTxBytes - currentTxBytes;
      uint32_t dataOffset = currentTxBytes % writeSize;
      uint32_t toWrite = writeSize - dataOffset;
      toWrite = std::min (toWrite, left);
      toWrite = std::min (toWrite, localSocket->GetTxAvailable ());
      //writecount++;
      int amountSent = localSocket->Send (0, toWrite, 0);//&data[dataOffset]
      if(amountSent < 0)
        {
          // we will be called again when new tx space becomes available.
          return;
        }
      currentTxBytes += amountSent;
    }     
}

wscript

## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-

def build(bld):
    obj = bld.create_ns3_program('tcpthroughput',
                                 ['point-to-point', 'applications', 'network', 'traffic-control','internet','core'])
    obj.source = 'tcpthroughput.cc'
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010643777/article/details/80693649
个人分类: 仿真
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭