SoonyangZhang / ns3-tcp-bbr

implement TCP BBR in ns3.33
GNU General Public License v2.0
35 stars 21 forks source link

如何在链路带宽变化的场景下测试bbr的带宽探测性能? #10

Closed Jadaeu closed 8 months ago

Jadaeu commented 8 months ago

作者您好!实际中网络带宽往往不是一直恒定的,而是时刻变化的,请问能否通过对tcp-test.cc进行修改以实现链路带宽变化的场景呢?例如每隔5秒带宽变化一次。我目前是对tcp-test.cc中尝试进行改进,但是都没有成功实现。。下面是我的代码(自己写的部分都注释了):

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2021 Northeastern University, China
 *
 * 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
 *
 * Authors: SongyangZhang <sonyang.chang@foxmail.com>
 * URL: https://github.com/SoonyangZhang/ns3-tcp-bbr
*/
#include <string>
#include <unistd.h>
#include<stdio.h>
#include <iostream>
#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 "ns3/tcp-client-module.h"
using namespace ns3;
using namespace std;

NS_LOG_COMPONENT_DEFINE ("TcpTest");
static const double startTime=0;
static const double simDuration= 300.0;
#define DEFAULT_PACKET_SIZE 1500
static NodeContainer BuildExampleTopo (uint32_t bps,
                                       uint32_t msDelay,
                                       uint32_t msQdelay,
                                       bool enable_random_loss=false)
{
    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);
    int packets=bufSize/DEFAULT_PACKET_SIZE;
    NS_LOG_INFO("buffer packet "<<packets);
    pointToPoint.SetQueue ("ns3::DropTailQueue",
                           "MaxSize", StringValue (std::to_string(1)+"p"));
    NetDeviceContainer devices = pointToPoint.Install (nodes);

    InternetStackHelper stack;
    stack.Install (nodes);

    TrafficControlHelper pfifoHelper;
    uint16_t handle = pfifoHelper.SetRootQueueDisc ("ns3::FifoQueueDisc", "MaxSize", StringValue (std::to_string(packets)+"p"));
    pfifoHelper.AddInternalQueues (handle, 1, "ns3::DropTailQueue", "MaxSize",StringValue (std::to_string(packets)+"p"));
    pfifoHelper.Install(devices);
    Ipv4AddressHelper address;
    std::string nodeip="10.1.1.0";
    address.SetBase (nodeip.c_str(), "255.255.255.0");
    address.Assign (devices);
    if(enable_random_loss){
        std::string errorModelType = "ns3::RateErrorModel";
        ObjectFactory factory;
        factory.SetTypeId (errorModelType);
        Ptr<ErrorModel> em = factory.Create<ErrorModel> ();
        devices.Get (1)->SetAttribute ("ReceiveErrorModel", PointerValue (em));
    }
    return nodes;
}
//ChangeLinkBandwidth是本人写的
void ChangeLinkBandwidth(Ptr<Node> node, uint32_t newBw)
{
    Ptr<NetDevice> device = node->GetDevice(0);
    Ptr<PointToPointNetDevice> p2pDevice = DynamicCast<PointToPointNetDevice>(device);
    p2pDevice->GetChannel()->SetAttribute("DataRate", DataRateValue(DataRate(newBw)));
}

// ./waf --run "scratch/tcp-test --cc=bbr --folder=bbr"
int main(int argc, char *argv[])
{
    LogComponentEnable("TcpTest", LOG_LEVEL_ALL);
    LogComponentEnable("TcpClient", LOG_LEVEL_ALL);
    LogComponentEnable("TcpBbr", LOG_LEVEL_ALL);
    std::string cc("bbr2");
    std::string folder_name("default");
    CommandLine cmd;
    cmd.AddValue ("cc", "congestion algorithm",cc);
    cmd.AddValue ("folder", "folder name to collect data", folder_name);
    cmd.Parse (argc, argv);
    uint32_t kMaxmiumSegmentSize=1400;
    Config::SetDefault("ns3::TcpSocket::SndBufSize", UintegerValue(200*kMaxmiumSegmentSize));
    Config::SetDefault("ns3::TcpSocket::RcvBufSize", UintegerValue(200*kMaxmiumSegmentSize));
    Config::SetDefault("ns3::TcpSocket::SegmentSize",UintegerValue(kMaxmiumSegmentSize));
    if(0==cc.compare("reno")||0==cc.compare("bic")||0==cc.compare("cubic")||
      0==cc.compare("bbr")||0==cc.compare("copa")){}
    else{
        NS_ASSERT_MSG(0,"please input correct cc");
    }
    std::string trace_folder;

    {
        char buf[FILENAME_MAX];
        std::string trace_path=std::string (getcwd(buf, FILENAME_MAX))+"/traces/";
        trace_folder=trace_path+folder_name+"/";
        MakePath(trace_folder);
        TcpBbrDebug::SetTraceFolder(trace_folder.c_str());
        TcpTracer::SetTraceFolder(trace_folder.c_str());
    }
    uint32_t link_bw=500000;//链路带宽-网络连接的最大数据传输速率
    uint32_t link_owd=50;//单向传输时延-数据从发送端到接收端的单向传播延迟(毫秒)
    uint32_t q_delay=200;//队列延迟-数据在网络中的排队等待时间

    NodeContainer topo;
    topo=BuildExampleTopo(link_bw,link_owd,q_delay);
    Ptr<Node> h1=topo.Get(0);
    Ptr<Node> h2=topo.Get(1);

    //for utility
    TcpTracer::SetExperimentInfo(1,link_bw);
    //for loss rate
    TcpTracer::SetLossRateFlag(true);

    uint16_t serv_port = 5000;
    //install server on h2
    Address tcp_sink_addr;
    {
        Ptr<Ipv4> ipv4 = h2->GetObject<Ipv4> ();
        Ipv4Address serv_ip= ipv4->GetAddress (1, 0).GetLocal();
        InetSocketAddress socket_addr=InetSocketAddress{serv_ip,serv_port};
        tcp_sink_addr=socket_addr;
        Ptr<TcpServer> server=CreateObject<TcpServer>(tcp_sink_addr);
        h2->AddApplication(server);
        server->SetStartTime (Seconds (0.0));
    }

    uint64_t totalTxBytes = 400000*1500;
    {
        Ptr<TcpClient>  client= CreateObject<TcpClient> (totalTxBytes,TcpClient::E_TRACE_RTT|TcpClient::E_TRACE_INFLIGHT|TcpClient::E_TRACE_RATE);
        h1->AddApplication(client);
        client->ConfigurePeer(tcp_sink_addr);
        client->SetCongestionAlgo(cc);
        client->SetStartTime (Seconds (startTime));
        client->SetStopTime (Seconds (simDuration));
    }
    //下面两个Schedule也是本人写的
    Simulator::Schedule(Seconds(startTime + 10.0), &ChangeLinkBandwidth, h1, 2000000); // Change bandwidth to 0.5M after 10 seconds
    Simulator::Schedule(Seconds(startTime + 15.0), &ChangeLinkBandwidth, h1, 4000000); // Change bandwidth to 2M after 15 seconds
    Simulator::Stop (Seconds (simDuration+30.0));
    Simulator::Run ();

    Simulator::Destroy ();
    return 0;

}

- 
SoonyangZhang commented 8 months ago

Refer to: https://blog.csdn.net/u010643777/article/details/80590045

https://github.com/SoonyangZhang/DrainQueueCongestion/blob/master/scratch/bbr-resp.cc#L27

Jadaeu commented 8 months ago

Thank you so much!!