》》》》》ns-lib.tcl
Simulator instproc simplex-link { n1 n2 bw delay qtype args } {
# *********************************************
# **** 从下面中的default:,可以看出该命*******
# ****令主要使用了c++中的SimpleLink类来实现**
# *****该类实现了点对点的、有延迟的link其中,*
# *****延迟由类LinkDelay实现********
# *********************************************
......
# *********************************************************************
# *********************************************************************
default {
set link_($sid:$did) [new SimpleLink /
$n1 $n2 $bw $delay $q]
}
# *********************************************************************
# ********************************************************************
....
}
>>>>>>>>>ns-link.tcl
SimpleLink instproc init { src dst bw delay q {lltype "DelayLink"} } {
#
# lltype被赋值
#
$self next $src $dst
$self instvar link_ queue_ head_ toNode_ ttl_
# link_ :指向完成延迟和带宽计算的对象,默认为C++中的LinkDelay对象
# queue_ :指向链路的主队列元素
# head_ :链路的入口
# ttl_ :指向完成TTL计算的对象(c++的类TTLChecker实现的)
# drophead_:指向对分组丢弃的对象
# queue_ :事先定义好的
# 注意在该链路创建时,其链路延迟模块(set link_ [new $lltype])
# 和分组生存期模块(set ttl_ [new TTLChecker])也同时被创建了
# 同时对分组丢弃的对象也被创建了
$self instvar drophead_
set ns [Simulator instance]
# ****************************************
set drophead_ [new Connector]
$drophead_ target [$ns set nullAgent_]
# ****************************************
set head_ [new Connector]
$head_ set link_ $self
#set head_ $queue_ -> replace by the following
# xxx this is hacky
if { [[$q info class] info heritage ErrModule] == "ErrorModule" } {
$head_ target [$q classifier]
} else {
$head_ target $q
}
set queue_ $q
# **********************
set link_ [new $lltype]
# **********************
$link_ set bandwidth_ $bw
$link_ set delay_ $delay
$queue_ target $link_
$link_ target [$dst entry]
$queue_ drop-target $drophead_
# XXX
# put the ttl checker after the delay
# so we don't have to worry about accounting
# for ttl-drops within the trace and/or monitor
# fabric
#
# **********************
set ttl_ [new TTLChecker]
# **********************
$ttl_ target [$link_ target]
$self ttl-drop-trace
$link_ target $ttl_
# Finally, if running a multicast simulation,
# put the iif for the neighbor node...
if { [$ns multicast?] } {
$self enable-mcast $src $dst
}
$ns instvar srcRt_
if [info exists srcRt_] {
if { $srcRt_ == 1 } {
$self enable-src-rt $src $dst $head_
}
}
}
void LinkDelay::recv(Packet* p, Handler* h)
{
// 其父类为Connector,它要么把分组递交给target_
// 对象,要么将该分组给drop_丢弃。Connector子类
// 还有queue、TTLChecker等。他们一般都通过重载
// recv函数(非virtual函数)来实现自己独特的功能。
// 链路延迟模块
// 完成根据本分组的大小计算其发送延迟,
// 然后据该延迟将在分组缓存队列中的下
// 一个分组被插入链路模块这件事插入调
// 度器,即只有在链路延
// 迟模块中的分组被转发到链路上时,下
// 一个分组才可以进入链路延迟模块。当
// 然这个过程中,还将发送延迟加上传输
// 延迟后,被转发到TTL_上处理,作为一
// 个事件插入到调度器.
// 可以认为转发到TTL_上时,分组已经在
// 链路上传输完毕。即该模块在链路的令
// 一端
double txt = txtime(p);//计算分组发送延迟
Scheduler& s = Scheduler::instance();
if (dynamic_) {
Event* e = (Event*)p;
e->time_= txt + delay_;
itq_->enque(p); // for convinience, use a queue to store packets in transit
s.schedule(this, p, txt + delay_);
} else if (avoidReordering_) {
// code from Andrei Gurtov, to prevent reordering on
// bandwidth or delay changes
double now_ = Scheduler::instance().clock();
if (txt + delay_ < latest_time_ - now_ && latest_time_ > 0) {
latest_time_+=txt;
s.schedule(target_, p, latest_time_ - now_ );
} else {
latest_time_ = now_ + txt + delay_;
s.schedule(target_, p, txt + delay_);
// 该target_指向在ns-link.tcl中SimpleLink类的init过程中的ttl_
}
} else {
s.schedule(target_, p, txt + delay_);
}
s.schedule(h, &intr_, txt);
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sayigood/archive/2008/12/15/3524292.aspx