织梦贷款网站模板,国外产品推广是怎么做的,飞享套餐,网页制作与设计课本目录
一、源码
二、详解
1.定义日志和命名空间
2.注册Typeld类:TcpVegas和GetTypeId方法的实现
3.构造函数和析构函数
4.TcpVegas类中成员函数
(1) Fork函数
(2) PktsAcked函数
(3) EnableVegas函数
(4) DisableVegas函数 一、源码
/* -*- Mode:C; c-file-style:; c-file-style:gnu; indent-tabs-mode:nil; -*- */
/** Copyright (c) 2016 ResiliNets, ITTC, University of Kansas** 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** Author: Truc Anh N. Nguyen annguyenittc.ku.edu** James P.G. Sterbenz jpgsittc.ku.edu, director* ResiliNets Research Group http://wiki.ittc.ku.edu/resilinets* Information and Telecommunication Technology Center (ITTC)* and Department of Electrical Engineering and Computer Science* The University of Kansas Lawrence, KS USA.*/#include tcp-vegas.h
#include tcp-socket-state.h#include ns3/log.hnamespace ns3 {NS_LOG_COMPONENT_DEFINE (TcpVegas);
NS_OBJECT_ENSURE_REGISTERED (TcpVegas);TypeId
TcpVegas::GetTypeId (void)
{static TypeId tid TypeId (ns3::TcpVegas).SetParentTcpNewReno ().AddConstructorTcpVegas ().SetGroupName (Internet).AddAttribute (Alpha, Lower bound of packets in network,UintegerValue (2),MakeUintegerAccessor (TcpVegas::m_alpha),MakeUintegerCheckeruint32_t ()).AddAttribute (Beta, Upper bound of packets in network,UintegerValue (4),MakeUintegerAccessor (TcpVegas::m_beta),MakeUintegerCheckeruint32_t ()).AddAttribute (Gamma, Limit on increase,UintegerValue (1),MakeUintegerAccessor (TcpVegas::m_gamma),MakeUintegerCheckeruint32_t ());return tid;
}TcpVegas::TcpVegas (void): TcpNewReno (),m_alpha (2),m_beta (4),m_gamma (1),m_baseRtt (Time::Max ()),m_minRtt (Time::Max ()),m_cntRtt (0),m_doingVegasNow (true),m_begSndNxt (0)
{NS_LOG_FUNCTION (this);
}TcpVegas::TcpVegas (const TcpVegas sock): TcpNewReno (sock),m_alpha (sock.m_alpha),m_beta (sock.m_beta),m_gamma (sock.m_gamma),m_baseRtt (sock.m_baseRtt),m_minRtt (sock.m_minRtt),m_cntRtt (sock.m_cntRtt),m_doingVegasNow (true),m_begSndNxt (0)
{NS_LOG_FUNCTION (this);
}TcpVegas::~TcpVegas (void)
{NS_LOG_FUNCTION (this);
}PtrTcpCongestionOps
TcpVegas::Fork (void)
{return CopyObjectTcpVegas (this);
}void
TcpVegas::PktsAcked (PtrTcpSocketState tcb, uint32_t segmentsAcked,const Time rtt)
{NS_LOG_FUNCTION (this tcb segmentsAcked rtt);if (rtt.IsZero ()){return;}m_minRtt std::min (m_minRtt, rtt);NS_LOG_DEBUG (Updated m_minRtt m_minRtt);m_baseRtt std::min (m_baseRtt, rtt);NS_LOG_DEBUG (Updated m_baseRtt m_baseRtt);// Update RTT counterm_cntRtt;NS_LOG_DEBUG (Updated m_cntRtt m_cntRtt);
}void
TcpVegas::EnableVegas (PtrTcpSocketState tcb)
{NS_LOG_FUNCTION (this tcb);m_doingVegasNow true;m_begSndNxt tcb-m_nextTxSequence;m_cntRtt 0;m_minRtt Time::Max ();
}void
TcpVegas::DisableVegas ()
{NS_LOG_FUNCTION (this);m_doingVegasNow false;
}void
TcpVegas::CongestionStateSet (PtrTcpSocketState tcb,const TcpSocketState::TcpCongState_t newState)
{NS_LOG_FUNCTION (this tcb newState);if (newState TcpSocketState::CA_OPEN){EnableVegas (tcb);}else{DisableVegas ();}
}void
TcpVegas::IncreaseWindow (PtrTcpSocketState tcb, uint32_t segmentsAcked)
{NS_LOG_FUNCTION (this tcb segmentsAcked);if (!m_doingVegasNow){// If Vegas is not on, we follow NewReno algorithmNS_LOG_LOGIC (Vegas is not turned on, we follow NewReno algorithm.);TcpNewReno::IncreaseWindow (tcb, segmentsAcked);return;}if (tcb-m_lastAckedSeq m_begSndNxt){ // A Vegas cycle has finished, we do Vegas cwnd adjustment every RTT.NS_LOG_LOGIC (A Vegas cycle has finished, we adjust cwnd once per RTT.);// Save the current right edge for next Vegas cyclem_begSndNxt tcb-m_nextTxSequence;/** We perform Vegas calculations only if we got enough RTT samples to* insure that at least 1 of those samples wasnt from a delayed ACK.*/if (m_cntRtt 2){ // We do not have enough RTT samples, so we should behave like RenoNS_LOG_LOGIC (We do not have enough RTT samples to do Vegas, so we behave like NewReno.);TcpNewReno::IncreaseWindow (tcb, segmentsAcked);}else{NS_LOG_LOGIC (We have enough RTT samples to perform Vegas calculations);/** We have enough RTT samples to perform Vegas algorithm.* Now we need to determine if cwnd should be increased or decreased* based on the calculated difference between the expected rate and actual sending* rate and the predefined thresholds (alpha, beta, and gamma).*/uint32_t diff;uint32_t targetCwnd;uint32_t segCwnd tcb-GetCwndInSegments ();/** Calculate the cwnd we should have. baseRtt is the minimum RTT* per-connection, minRtt is the minimum RTT in this window** little trick:* desidered throughput is currentCwnd * baseRtt* target cwnd is throughput / minRtt*/double tmp m_baseRtt.GetSeconds () / m_minRtt.GetSeconds ();targetCwnd static_castuint32_t (segCwnd * tmp);NS_LOG_DEBUG (Calculated targetCwnd targetCwnd);NS_ASSERT (segCwnd targetCwnd); // implies baseRtt minRtt/** Calculate the difference between the expected cWnd and* the actual cWnd*/diff segCwnd - targetCwnd;NS_LOG_DEBUG (Calculated diff diff);if (diff m_gamma (tcb-m_cWnd tcb-m_ssThresh)){/** We are going too fast. We need to slow down and change from* slow-start to linear increase/decrease mode by setting cwnd* to target cwnd. We add 1 because of the integer truncation.*/NS_LOG_LOGIC (We are going too fast. We need to slow down and change to linear increase/decrease mode.);segCwnd std::min (segCwnd, targetCwnd 1);tcb-m_cWnd segCwnd * tcb-m_segmentSize;tcb-m_ssThresh GetSsThresh (tcb, 0);NS_LOG_DEBUG (Updated cwnd tcb-m_cWnd ssthresh tcb-m_ssThresh);}else if (tcb-m_cWnd tcb-m_ssThresh){ // Slow start modeNS_LOG_LOGIC (We are in slow start and diff m_gamma, so we follow NewReno slow start);TcpNewReno::SlowStart (tcb, segmentsAcked);}else{ // Linear increase/decrease modeNS_LOG_LOGIC (We are in linear increase/decrease mode);if (diff m_beta){// We are going too fast, so we slow downNS_LOG_LOGIC (We are going too fast, so we slow down by decrementing cwnd);segCwnd--;tcb-m_cWnd segCwnd * tcb-m_segmentSize;tcb-m_ssThresh GetSsThresh (tcb, 0);NS_LOG_DEBUG (Updated cwnd tcb-m_cWnd ssthresh tcb-m_ssThresh);}else if (diff m_alpha){// We are going too slow (having too little data in the network),// so we speed up.NS_LOG_LOGIC (We are going too slow, so we speed up by incrementing cwnd);segCwnd;tcb-m_cWnd segCwnd * tcb-m_segmentSize;NS_LOG_DEBUG (Updated cwnd tcb-m_cWnd ssthresh tcb-m_ssThresh);}else{// We are going at the right speedNS_LOG_LOGIC (We are sending at the right speed);}}tcb-m_ssThresh std::max (tcb-m_ssThresh, 3 * tcb-m_cWnd / 4);NS_LOG_DEBUG (Updated ssThresh tcb-m_ssThresh);}// Reset cntRtt minRtt every RTTm_cntRtt 0;m_minRtt Time::Max ();}else if (tcb-m_cWnd tcb-m_ssThresh){TcpNewReno::SlowStart (tcb, segmentsAcked);}
}std::string
TcpVegas::GetName () const
{return TcpVegas;
}uint32_t
TcpVegas::GetSsThresh (Ptrconst TcpSocketState tcb,uint32_t bytesInFlight)
{NS_LOG_FUNCTION (this tcb bytesInFlight);return std::max (std::min (tcb-m_ssThresh.Get (), tcb-m_cWnd.Get () - tcb-m_segmentSize), 2 * tcb-m_segmentSize);
}} // namespace ns3
二、详解
1.定义日志和命名空间
#include tcp-vegas.h //包含TCP Vegas算法的头文件。
#include tcp-socket-state.h //包含TCP套接字状态的头文件#include ns3/log.h //包含NS-3日志功能的头文件namespace ns3 {NS_LOG_COMPONENT_DEFINE (TcpVegas); //定义了一个日志组件用于记录日志信息。
NS_OBJECT_ENSURE_REGISTERED (TcpVegas);
2.注册Typeld类:TcpVegas和GetTypeId方法的实现
TypeId
TcpVegas::GetTypeId (void)
{static TypeId tid TypeId (ns3::TcpVegas) //设置类的名称为TcpVegas 位于ns3命名空间下.SetParentTcpNewReno () //设置TcpVegas的父类为TcpNewReno.AddConstructorTcpVegas () //添加TcpVegas类的构造函数 创建相关对象.SetGroupName (Internet) //将TcpVegas分类到Internet组下.AddAttribute (Alpha, Lower bound of packets in network,UintegerValue (2),MakeUintegerAccessor (TcpVegas::m_alpha),MakeUintegerCheckeruint32_t ()).AddAttribute (Beta, Upper bound of packets in network,UintegerValue (4),MakeUintegerAccessor (TcpVegas::m_beta),MakeUintegerCheckeruint32_t ()).AddAttribute (Gamma, Limit on increase,UintegerValue (1),MakeUintegerAccessor (TcpVegas::m_gamma),MakeUintegerCheckeruint32_t ());return tid; //返回TcpVegas的TypeId对象
}
AddAttribute方法用于添加类的属性这些属性可以在NS-3的配置系统中设置和获取。 Alpha、Beta和Gamma是TcpVegas算法的三个参数它们分别控制算法的行为 Alpha网络中数据包的下界初始值为2。Beta网络中数据包的上界初始值为4。Gamma增加的极限初始值为1。UintegerValue设置属性的初始值。MakeUintegerAccessor创建一个访问器用于访问和修改属性值。MakeUintegerCheckeruint32_t()创建一个检查器确保属性值是有效的无符号整数。
该段代码在NS-3中注册TcpVegas类并设置其属性和行为使得TcpVegas可以在NS-3的模拟中被创建和配置。
3.构造函数和析构函数
TcpVegas::TcpVegas (void) //默认构造函数: TcpNewReno (), //TcpVegas通过调用其父类TcpNewReno的默认构造函数来进行初始化m_alpha (2),m_beta (4), m_gamma (1), m_baseRtt (Time::Max ()),m_minRtt (Time::Max ()),m_cntRtt (0),m_doingVegasNow (true),m_begSndNxt (0)
{NS_LOG_FUNCTION (this); //日志记录构造函数的调用this指向当前对象的指针
}TcpVegas::TcpVegas (const TcpVegas sock) //复制构造函数: TcpNewReno (sock),m_alpha (sock.m_alpha),m_beta (sock.m_beta),m_gamma (sock.m_gamma),m_baseRtt (sock.m_baseRtt),m_minRtt (sock.m_minRtt),m_cntRtt (sock.m_cntRtt),m_doingVegasNow (true),m_begSndNxt (0)
{NS_LOG_FUNCTION (this);
}TcpVegas::~TcpVegas (void) //析构函数
{NS_LOG_FUNCTION (this);
}
默认构造函数
m_alpha (2), m_beta (4), m_gamma (1)这些行初始化TcpVegas算法的参数alpha、beta和gamma分别设置为2、4和1。m_baseRtt (Time::Max ()), m_minRtt (Time::Max ())将基础往返时间baseRtt和最小往返时间minRtt初始化为最大时间值表示它们尚未被设置。m_cntRtt (0)初始化往返时间计数器cntRtt为0。即用于计数自连接建立以来观测到的RTT样本数量。m_doingVegasNow (true)初始化标志doingVegasNow为true表示Vegas算法默认是启用的。m_begSndNxt (0)初始化发送下一个序列号begSndNxt为0。日志系统记录构造函数的调用this指向当前对象的指针。
复制构造函数用于创建一个与另一个TcpVegas对象sock相同的新对象。
: TcpNewReno (sock)表明TcpVegas复制构造函数首先调用其父类TcpNewReno的复制构造函数来复制父类成员。接下来复制sock对象中的alpha、beta、gamma、baseRtt、minRtt和cntRtt成员变量的值到新对象。m_doingVegasNow (true)和m_begSndNxt (0)与默认构造函数类似初始化doingVegasNow为true和begSndNxt为0。const TcpVegas sock参数sock是TcpVegas类型的对象引用它指向一个已经存在的对象
4.TcpVegas类中成员函数
(1) Fork函数
PtrTcpCongestionOps
TcpVegas::Fork (void)
{return CopyObjectTcpVegas (this);
}Fork函数用于创建当前TcpVegas对象的一个副本并返回这个副本的智能指针PtrTcpCongestionOps是一个智能指针指向TcpCongestionOps类型的对象。Ptr是NS-3中用于管理对象生命周期的智能指针模板类而TcpCongestionOps是一个抽象基类代表TCP拥塞控制操作。CopyObjectTcpVegas (this)这是NS-3中用于复制对象的模板函数它创建了当前对象的一个副本并返回一个指向新对象的智能指针。这里的this指针指向当前的TcpVegas对象。
(2) PktsAcked函数
void
TcpVegas::PktsAcked (PtrTcpSocketState tcb, uint32_t segmentsAcked,const Time rtt)
{NS_LOG_FUNCTION (this tcb segmentsAcked rtt);if (rtt.IsZero ()){return;}m_minRtt std::min (m_minRtt, rtt);NS_LOG_DEBUG (Updated m_minRtt m_minRtt);m_baseRtt std::min (m_baseRtt, rtt);NS_LOG_DEBUG (Updated m_baseRtt m_baseRtt);// Update RTT counterm_cntRtt;NS_LOG_DEBUG (Updated m_cntRtt m_cntRtt);
}
PktsAcked函数在收到ACK时被调用用于更新最小 RTTm_minRtt和基础 RTTm_baseRtt并统计 RTT 样本的数量 (m_cntRtt)。如果 rtt 为零则直接返回不进行任何操作。这通常是为了避免处理无效的数据例如无效的 ACK 或零延迟的情况。std::min 是 C 标准库中的一个函数模板它返回两个参数中的较小值。m_minRtt 表示当前连接或当前窗口内的最小 RTT。在每次收到 ACK 包时如果新的 RTT 比当前记录的 m_minRtt 小就会更新 m_minRtt。 std::min(m_minRtt, rtt) 会选择 m_minRtt 和当前 RTT 中较小的一个并将其赋值给 m_minRtt。确保 m_minRtt 始终保持为最小的 RTT 值。m_baseRtt 用于记录连接过程中观察到的最小 RTT通常是在连接的初期或网络的稳定阶段。这代表了网络的基准延迟即理想的延迟。与 m_minRtt 类似m_baseRtt 会更新为当前 RTT 和已有的 m_baseRtt 中的最小值。这可以确保 m_baseRtt 始终为连接期间的最小延迟。m_cntRtt 是 RTT 样本的计数器。每次收到 ACK 包时都会增加 m_cntRtt 的值表示新的 RTT 样本被记录。
baseRtt 和 minRtt的区别见
TCP Vegas拥塞控制算法——baseRtt 和 minRtt的区别-CSDN博客
(3) EnableVegas函数
void
TcpVegas::EnableVegas (PtrTcpSocketState tcb)
{NS_LOG_FUNCTION (this tcb);m_doingVegasNow true;m_begSndNxt tcb-m_nextTxSequence;m_cntRtt 0;m_minRtt Time::Max ();
}void
TcpVegas::DisableVegas ()
{NS_LOG_FUNCTION (this);m_doingVegasNow false;
}
EnableVegas函数用于启用Vegas算法。m_doingVegasNow标志被设置为true表示Vegas算法现在被激活。m_begSndNxt被设置为下一个传输序列号用于跟踪Vegas周期的开始。将m_cntRtt成员变量重置为0在每个新的Vegas周期开始时重置这个计数器。将m_minRtt重置为Time::Max()即最大可能的时间值用于在新的Vegas周期中重新寻找最小的RTT值。
(4) DisableVegas函数
void TcpVegas::DisableVegas ()
{NS_LOG_FUNCTION (this);m_doingVegasNow false;
}
DisableVegas函数用于禁用Vegas算法。m_doingVegasNow标志被设置为false表示Vegas算法现在被禁用。