1、 创建简单的有线-无线混合场景
上一节建立的无线仿真可以支持多跳adhoc网络或wirelesslan。但是,我们可能需要对经过有线网络连接的多个无线网络进行仿真,或者说我们需要对有线-无线混合网络进行仿真。
本节,我们将对上节的简单无线仿真场景进行扩展,建立一个混合场景,数据在可移动和不可移动节点间传递。我们将修改 XI.2的脚本wireless1.tcl,重新命名为wireless2.tcl。
对于混合场景,我们将创建两个有线节点:W(0)和W(1),通过一个基站BS与一个含有3个无线节点的无线网络相连。BS作为一个连接有线网和无线网的网关,可以在两者之间转发数据。关于BS的详细信息,请参考ns手册第15章第2节,下图显示了这个拓扑:
首先检查一下对于wireless1.tcl中定义的变量有什么需要修改的地方。
Adhoc路由协议修改为DSDV。另外我们定义了有线节点和无线节点间的Tcp CBR流,因此也就不再需要原来定义的模型文件了,仿真结束时间也需要修改,注意,在这里我们用opt()队列代替val()队列,这仅仅表示现在它是一个局部变量,而不是全局变量。
set opt(adhocRouting) DSDV
set opt(cp) "" ;# cp file not used
set opt(stop) 300 ;# time to stop simulation
现在定义TCP流开始的时间:
set opt(ftp1-start) 160.0
set opt(ftp2-start) 170.0
还要加上下面的语句,定义有线节点和基站的数目:
set num_wired_nodes 2
set num_bs_nodes 1
现在,我们开始程序的主要部分。对于混合网络,我们需要使用分层路由以便能够在有线网和无线网之间传递数据包。正如ns手册15.2.1中所说,在ns中,有线网络中的路由信息是基于拓扑连接关系的,即,节点之间的链路是如何连接的。Ns使用这个连接信息在节点之间传播转发表。然而无线节点中没有链路的概念,数据包在无线拓扑中根据adhoc路由选路,这种路由根据邻居之间传递的路由请求信息建立转发表。因此,想在有线和无线节点之间传递数据,我们必须使用基站作为连接两个域的网关。我们通过分层拓扑结构定义域和子域(或叫做簇)。在"set ns [new Simulator]"这条语句之后加入下列语句:
$ns_ node-config -addressType hierarchical
AddrParams set domain_num_ 2 ;# number of domains
lappend cluster_num 2 1 ;# number of clusters in each
;#domain
AddrParams set cluster_num_ $cluster_num
lappend eilastlevel 1 1 4 ;# number of nodes in each cluster
AddrParams set nodes_num_ $eilastlevel ;# for each domain
在上面的代码中,我们首先将节点对象的地址类型配置为分层:hierarchical。随后定义了拓扑结构。在这个拓扑中,域的数量是2,域中的节点数定义为2 1,意思是,第一个域(有线域)有两个簇,第二个域(无线域)有一个簇。下面一行代码定义了在每个簇中的节点数:"1 1 4",即,在前面两个簇中,每个簇有一个节点,第三个簇中有4个节点。于是,拓扑被定义成一个三层结构。
下面我们建立仿真的trace文件。注意,对于混合网络仿真可能对两个域都产生trace文件。两个域的trace都写到同一个文件中:wireless2-out.tr。为了区分有线和无线两种trace,所有无线trace以"WL"开头。我们还建立了nam trace,前面提到过,无线仿真中nam只能显示节点移动。
set tracefd [open wireless2-out.tr w]
set namtrace [open wireless2-out.nam w]
$ns_ trace-all $tracefd
$ns_ namtrace-all-wireless $namtrace $opt(x) $opt(y)
下面我们需要创建无线、有线、基站节点。这里请注意,创建节点时,需要给节点传递分层地址,于是,在"create-god $opt(nn)"后面加入下列代码:
# create wired nodes
set temp {0.0.0 0.1.0} ;# hierarchical addresses to be used
for {set i 0} {$i < $num_wired_nodes} {incr i} {
set W($i) [$ns_ node [lindex $temp $i]]
}
为了创建基站节点,我们需要按照下面的方法配置节点。这是节点的一个新api,包括先配置节点然后创建节点。关于节点新的api请参考第IX章的node API。由于基站节点作为两个网络的网关,它需要开启有线网的路由协议,这可以通过-wiredRouting ON选项指定。在创建了基站节点之后,我们再重新配置无线节点,设置wiredRouting OFF。用于基站的其他配置都可以用于无线节点。还要把无线节点的基站节点指定为BS(0),于是,所有从无线节点发往有线节点的数据包都将被转发到BS(0)。
注意,需要把基站节点放到和无线节点同一个域中,这样,从有线节点发送到无线节点的数据包才能通过基站然后通过adhoc路由到达无线节点。于是,对于混合网络,需要:
打开分层路由
为有线节点和无线节点创建不同的域。可以有多个有线或无线域。
每个无线域中都要有一个基站,通过它,无线节点可以和其他节点通信。
我们将一步步演示如何创建分层路由。现在我们有两个域,0是有线域,1是无线域。两个有线节点被放在0和1两个簇中,于是他们的地址看起来象这样:0(domain 0).0(cluster 0).0(only node)和0 (same domain 0).1(cluster 1).0(again only node)。
对于无线节点,他们在域1,我们在其中定义了一个簇,于是,所有节点在同一个簇中,他们的地址为:
WL node#1 : 1.0.1(second node in cluster)
WL node#2 : 1.0.2(third node)
WL node#3 : 1.0.3(fourth node)
当然,我们可以把两个有线节点放在同一个簇中,也可以把多个无线节点放到不同的簇中。同样,根据我们的拓扑,也可以根本不要簇,而只用一个两层地址结构:域和节点。
# configure for base-station node
$ns_ node-config -adhocRouting $opt(adhocRouting) \
-llType $opt(ll) \
-macType $opt(mac) \
-ifqType $opt(ifq) \
-ifqLen $opt(ifqlen) \
-antType $opt(ant) \
-propType $opt(prop) \
-phyType $opt(netif) \
-channelType $opt(chan) \
-topoInstance $topo \
-wiredRouting ON \
-agentTrace ON \
-routerTrace OFF \
-macTrace OFF
#create base-station node
set temp {1.0.0 1.0.1 1.0.2 1.0.3} ;# hier address to be used for
;# wireless domain
set BS(0) [ $ns_ node [lindex $temp 0]]
$BS(0) random-motion 0 ;# disable random motion
#provide some co-ordinates (fixed) to base station node
$BS(0) set X_ 1.0
$BS(0) set Y_ 2.0
$BS(0) set Z_ 0.0
# create mobilenodes in the same domain as BS(0)
# note the position and movement of mobilenodes is as defined
# in $opt(sc)
# Note there has been a change of the earlier AddrParams
# function 'set-hieraddr' to 'addr2id'.
#configure for mobilenodes
$ns_ node-config -wiredRouting OFF
# now create mobilenodes
for {set j 0} {$j < $opt(nn)} {incr j} {
set node_($j) [ $ns_ node [lindex $temp \
[expr $j+1]] ]
$node_($j) base-station [AddrParams addr2id \
[$BS(0) node-addr]] ;# provide each mobilenode with
;# hier address of its base-station
}
下面连接有线节点和BS,并和无线节点、node_(0)和node W(0)之间,W(1)和 node_(2)之间建立tcp连接。
#create links between wired and BS nodes
$ns_ duplex-link $W(0) $W(1) 5Mb 2ms DropTail
$ns_ duplex-link $W(1) $BS(0) 5Mb 2ms DropTail
$ns_ duplex-link-op $W(0) $W(1) orient down
$ns_ duplex-link-op $W(1) $BS(0) orient left-down
# setup TCP connections
set tcp1 [new Agent/TCP]
$tcp1 set class_ 2
set sink1 [new Agent/TCPSink]
$ns_ attach-agent $node_(0) $tcp1
$ns_ attach-agent $W(0) $sink1
$ns_ connect $tcp1 $sink1
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1
$ns_ at $opt(ftp1-start) "$ftp1 start"
set tcp2 [new Agent/TCP]
$tcp2 set class_ 2
set sink2 [new Agent/TCPSink]
$ns_ attach-agent $W(1) $tcp2
$ns_ attach-agent $node_(2) $sink2
$ns_ connect $tcp2 $sink2
set ftp2 [new Application/FTP]
$ftp2 attach-agent $tcp2
$ns_ at $opt(ftp2-start) "$ftp2 start"
后面就是原来脚本剩下的部分。wireless2.tcl中可能有写代码没有在此讨论,完整的代码可以在这下载:http://www.isi.edu/nsnam/ns/tutorial/examples/wireless2.tcl
运行这个脚本,在执行的最后将生成ns和nam的trace文件。运行wireless2-out.nam将显示无线节点的运动。在wireless2-out.tr中,我们可以看到有线域和无线域的trace。在160秒的时候,在节点_3_, (即node_(0)) 和0, (即W(0))之间建立了一条Tcp连接,注意,节点id是仿真器内部指定并根据节点创建顺序分配的。在170秒时,另一个反向的Tcp连接建立。关于CMUTraces的详细信息请参考ns手册第15章。
1、 在一个简单混合拓扑上运行移动ip
到目前为止,我们已经创建了一个有线-无线混合拓扑并且可以通过基站在有线节点和无线节点之间交换数据包了。但是,一个无线节点可能会漫游到它的基站的覆盖范围之外,此时,它仍然应该可以接收发向它的数据包。换句话说,在混合拓扑中支持移动ip应该很有趣。
在这个例子中的有线节点W0和W1和前面例子中完全相同。有两个基站,一个叫做HomeAgent(HA),另外一个叫做ForeignAgent(FA)。有线节点W1与两个基站的连接方式如下图:
拓扑中有一个移动节点叫做MobileHost(MH),它在HA和FA之间移动。我们将在W0和MH建立TCP流。当MH移动出HA域并进入FA域时,我们可以看到以MH为目的地的数据包是如何被HA根据移动ip协议的定义重定向到FA的。
我们把wireless2.tcl修改一下,创建一个无线移动ip脚本,叫做wireless3.tcl。这里可能不会完整的讨论这个脚本,为方便起见,可以从http://www.isi.edu/nsnam/ns/tutorial/examples/wireless3.tcl下载一份该脚本的拷贝。
首先将移动节点数修改为1:
set opt(nn) 1 ;# just one MH
set opt(stop) 250
在这个例子中,我们将在脚本中定义节点的移动和TCP连接,因此不需要原来读取cp和sc文件:
set opt(cp) ""
set opt(sc) ""
定义TCP的开始时间:
set opt(ftp1-start) 100.0
修改有线节点,基站的数目,但是在这个脚本中的这个变量实际并没有被使用,基站节点HA和FA都是独立创建的。
set num_wired_nodes 2
在创建ns实例并设置了地址分层格式后,加入下面几行代码用来定义拓扑层次。和wireless2.tcl很象,除了现在我们有了第三个FA域,并相应修改了簇和节点的参数。
AddrParams set domain_num_ 3 ;# number of domains
lappend cluster_num 2 1 1 ;# number of clusters in each domain
AddrParams set cluster_num_ $cluster_num
lappend eilastlevel 1 1 2 1 ;# number of nodes in each cluster
AddrParams set nodes_num_ $eilastlevel ;# of each domain
于是,在这个拓扑中,我们有一个有线域,以0标记,两个无线域,分别以1和2标记。和上一节中一样,节点的地址还不变,分别是0.0.0和0.1.0。在第一个无线域(1)中,我们有一个基站HA和一个移动节点MH,它们在同一个簇中。地址分别是1.0.0和1.0.1。在第二个无线域(2)中,我们有一个基站FA,地址是2.0.0。然而,在仿真过程中,MH将移动到FA的域中,我们可以看到作为移动ip的结果,从有线域到无线域中节点的数据包是如何被转发的。
有线节点的创建和以前一样,但是这次将创建HA和FA而不是一个基站,注意,在这里为了打开移动ip标志开关,我们必须将节点结构配置为-mobileIP ON:
# Configure for ForeignAgent and HomeAgent nodes
$ns_ node-config -mobileIP ON \
-adhocRouting $opt(adhocRouting) \
-llType $opt(ll) \
-macType $opt(mac) \
-ifqType $opt(ifq) \
-ifqLen $opt(ifqlen) \
-antType $opt(ant) \
-propType $opt(prop) \
-phyType $opt(netif) \
-channelType $opt(chan) \
-topoInstance $topo \
-wiredRouting ON \
-agentTrace ON \
-routerTrace OFF \
-macTrace OFF
# Create HA and FA
set HA [$ns_ node 1.0.0]
set FA [$ns_ node 2.0.0]
$HA random-motion 0
$FA random-motion 0
#provide some co-ord (fixed) to these base-station nodes.
$HA set X_ 1.000000000000
$HA set Y_ 2.000000000000
$HA set Z_ 0.000000000000
$FA set X_ 650.000000000000
$FA set Y_ 600.000000000000
$FA set Z_ 0.000000000000
然后按下面的步骤创建移动节点。注意象以前一样,我们关闭选项-wiredRouting(这是用来创建基站节点的)。HA被设置为移动节点的家乡代理。MH有一个叫做关心地址的地址(COA:care-of-address)。通过移动节点和基站之间交换注册/信标消息,基站将自己的地址分配给移动节点作为其COA。于是,在这个仿真中,一开始将HA的地址作为COA分配给MH。当MH移动到FA域时,它的COA将变为FA的地址。关于ns中移动ip的细节问题,参考ns手册的15.2.2。另外文件mip.cc mip.h mip-reg.cc mip-reg.h tcl/lib/ns-mip.tcl, ns-wireless-mip.tcl也可以作为参考。
# configure for mobilehost
$ns_ node-config -wiredRouting OFF
# create mobilehost that would be moving between HA and FA.
# note address of MH indicates its in the same domain as HA.
set MH [$ns_ node 1.0.1]
set node_(0) $MH
set HAaddress [AddrParams set-hieraddr [$HA node-addr]]
[$MH set regagent_] set home_agent_ $HAaddress
# movement of the MH
$MH set Z_ 0.000000000000
$MH set Y_ 2.000000000000
$MH set X_ 2.000000000000
# MH starts to move towards FA (640, 610) at a speed of 20m/s
$ns_ at 100.000000000000 "$MH setdest 640.000000000000 610.000000000000
20.000000000000"
# and goes back to HA (2, 2) at a speed of 20 m/s
$ns_ at 200.000000000000 "$MH setdest 2.000000000000 2.000000000000
20.000000000000"
在有线节点和HA/FA间创建链路,并建立TCP连接:
# create links between wired and BaseStation nodes
$ns_ duplex-link $W(0) $W(1) 5Mb 2ms DropTail
$ns_ duplex-link $W(1) $HA 5Mb 2ms DropTail
$ns_ duplex-link $W(1) $FA 5Mb 2ms DropTail
$ns_ duplex-link-op $W(0) $W(1) orient down
$ns_ duplex-link-op $W(1) $HA orient left-down
$ns_ duplex-link-op $W(1) $FA orient right-down
# setup TCP connections between a wired node and the MobileHost
set tcp1 [new Agent/TCP]
$tcp1 set class_ 2
set sink1 [new Agent/TCPSink]
$ns_ attach-agent $W(0) $tcp1
$ns_ attach-agent $MH $sink1
$ns_ connect $tcp1 $sink1
set ftp1 [new Application/FTP]
$ftp1 attach-agent $tcp1
$ns_ at $opt(ftp1-start) "$ftp1 start"
脚本的剩余部分不用改变。保存并执行这个脚本。在http://www.isi.edu/nsnam/ns/tutorial/examples/wireless3.tcl可以下载一个wireless3.tcl脚本。
在脚本运行过程中,你可能会看到一些警告:
"warning: Route to base_stn not known: dropping pkt"
这表示MH从一个域移动到另一个域的过程中由于暂时没有注册到任何一个基站,因此不知道该把数据包向谁发送。运行结束后,生成的ns和nam的trace文件是:"wireless3-out.tr"和"wireless3-out.nam"。 nam的输出文件可以显示出节点的移动,以及有线域中的数据流。 Ns输出文件中含有有线节点和无线节点的所有数据。我们还可以看到周期性信标消息广播。一开始TCP数据包直接由HA转发给MH,当MH移动到HA域之外而进入FA域后,去往MH的数据包被封装并转发给FA,然后在解封装后转发给MH。