ns-2与TCP拥塞模拟 之六 ns-2 TCP拥塞控制核心模块-变量说明
C++中继承TcpAgent的子类
我们先从测试的角度来看,TCP代理模块都暴露了哪些属性给OTcl脚本,也就是说,用set命令可以得到哪些属性。
TCP发送端的设定参数如下所示。
表TCP发送端的设定参数
fid_ |
TCP连接的编号(Flow ID) |
window_ |
通告窗口(Advertised Window)的上限值(upper bond)。通告窗口指的是接收端的缓冲区可以容纳的数据包个数。因此当拥塞窗口的值超过通告窗口时,TCP的发送端会执行流量控制,以避免发送得太快而导致接收端的缓冲区溢出 |
maxcwnd_ |
拥塞窗口的最大值 |
windowInit |
拥塞窗口的初始值 |
ecn_ |
True表示使用ECN |
packetSize_ |
发送包的数据大小 |
tcpTick_ |
TCP的超时时间(默认值为0.01s) |
maxburst_ |
每收到一个ACK触发的发送端最多能送出的数据包的个数。0表示关闭此选项功能 |
TCP接收端的设定参数如下所示。
表 TCP接收端的设定参数
packetSize_ |
ACK包的尺寸大小 |
TCP发送端的状态参数如下所示。
表 TCP发送端的状态参数
dupacks_ |
重复ACK包的个数 |
t_seqno_ |
目前传送的包序号 |
ssthresh_ |
慢启动阈值 |
cwnd_ |
拥塞窗口的值 |
ack_ |
发送端最后收到的ACK序号 |
maxseq_ |
发送端最后发出的包序号 |
TCP Vegas的特殊参数如表所示。
表 TCP Vegas的特殊参数
v_alpha_ |
a 值 |
v_beta_ |
b 值 |
v_gamma_ |
当队列长度≥g 时,Vegas由慢启动阶段进入拥塞避免阶段 |
这些属性中,用得比较多的是发送端的拥塞窗口值cwnd_。以下给出简单的读取示例。
……
#创建TCP连接
set tcp [ new Agent/TCP ]
……
#Record过程
set f0 [open cwn_out.tr w] ;#打开记录文件
proc Record {} { ;#定义记录过程
global f0 tcp ns ;#声明全局变量
setintval 0.1 ;#设定记录间隔时间
setnow [$ns now] ;#获取当前ns时间
setcwnd [$tcp set cwnd_] ;#获取当前cwnd值
puts $f0 "$now $cwnd" ;#将时间点和cwnd值记录到文件中
$nsat [expr $now + $intval] "Record" ;#定时调用记录过程
}
$ns at 0.1 "Record" ;#ns首次调用Record过程
……
示例中,还可以使用如下更直接的语句,将cwnd的值记录到文件中(若仅给出格式化字符串,则输出到控制台,也就是没有参数$f0):
puts $f0 "$now [$tcp set cwnd_]"
设定参数值的示例如下:
$tcp set packetSize_ 100.0
接下来,转到C++源码中bind函数相关的地方。以TcpAgent为例,文件tcp/tcp.cc中相关的代码如下:
TcpAgent::TcpAgent()
:Agent(PT_TCP),
t_seqno_(0), dupacks_(0), curseq_(0),highest_ack_(0),
cwnd_(0), ssthresh_(0), maxseq_(0), count_(0),
rtt_active_(0), rtt_seq_(-1), rtt_ts_(0.0),
lastreset_(0.0),closed_(0), t_rtt_(0), t_srtt_(0), t_rttvar_(0),
t_backoff_(0), ts_peer_(0), ts_echo_(0),tss(NULL), tss_size_(100),
rtx_timer_(this), delsnd_timer_(this),burstsnd_timer_(this),
first_decrease_(1), fcnt_(0), nrexmit_(0),restart_bugfix_(1),
cong_action_(0), ecn_burst_(0), ecn_backoff_(0), ect_(0),
use_rtt_(0), qs_requested_(0), qs_approved_(0),
qs_window_(0), qs_cwnd_(0), frto_(0)
{
#ifdef TCP_DELAY_BIND_ALL
// defined since Dec 1999.
#else /* ! TCP_DELAY_BIND_ALL */
bind("t_seqno_", &t_seqno_);
bind("rtt_", &t_rtt_);
bind("srtt_", &t_srtt_);
bind("rttvar_",&t_rttvar_);
bind("backoff_",&t_backoff_);
bind("dupacks_",&dupacks_);
bind("seqno_",&curseq_);
bind("ack_",&highest_ack_);
bind("cwnd_",&cwnd_);
bind("ssthresh_",&ssthresh_);
bind("maxseq_",&maxseq_);
bind("ndatapack_", &ndatapack_);
bind("ndatabytes_",&ndatabytes_);
bind("nackpack_", &nackpack_);
bind("nrexmit_",&nrexmit_);
bind("nrexmitpack_",&nrexmitpack_);
bind("nrexmitbytes_",&nrexmitbytes_);
bind("necnresponses_",&necnresponses_);
bind("ncwndcuts_", &ncwndcuts_);
bind("ncwndcuts1_",&ncwndcuts1_);
#endif /* TCP_DELAY_BIND_ALL */
}
可以看到,在TcpAgent的构造函数中,bind函数的主要目的是使Tcl的变量和C++的变量产生互连的关系,这样使用者就可以在Tcl脚本中去设定或者查看C++的变量值。还有类似的bind_bool函数,bind_bool用于绑定布尔变量;bind用于一般实数;函数中的第一个参数是Tcl的变量名,第二个参数是C++的变量名。功能类似的还有delay_bind函数。