Ns2简单有限网络仿真实验
1.编写Otcl脚本文件yy.tcl
2.终端:ns yy.tcl即可进行仿真
注意:在 建立一条UDP的联机时,不要忘记添加
$ns attach-agent $n3 $null
我在代码中也特别标注出来了。
//Otcl脚本,文本文件后缀名为.tcl即可
#产生一个仿真的对象
set ns [new Simulator]
#针对不同的资料流定义不同的颜色,这是要给NAM用的
$ns color 1 Green
$ns color 2 Red
#开启一个NAM trace file
set nf [open out.nam w]
$ns namtrace-all $nf
#开启一个trace file,用来记录封包传送的过程
set nd [open out.tr w]
$ns trace-all $nd
#定义一个结束的程序
proc finish {} {
global ns nf nd wnd_trace
$ns flush-trace
close $nf
close $nd
#以背景执行的方式去执行NAM
exec nam out.nam &
exit 0
}
#产生6个网络节点
set n0 [$ns node]
set n1 [$ns node]
set n2 [$ns node]
set n3 [$ns node]
set n4 [$ns node]
set n5 [$ns node]
#把节点连接起来
$ns duplex-link $n0 $n2 2Mb 10ms DropTail
$ns duplex-link $n1 $n2 2Mb 10ms DropTail
$ns duplex-link $n2 $n3 1.7Mb 20ms DropTail
$ns duplex-link $n3 $n4 1.7Mb 30ms DropTail
$ns duplex-link $n3 $n5 1.5Mb 30ms DropTail
#设定ns2到ns3之间的Queue Size为10个封包大小
$ns queue-limit $n2 $n3 10
$ns queue-limit $n3 $n4 5
$ns queue-limit $n3 $n5 10
#设定节点的位置,这是要给NAM用的
$ns duplex-link-op $n0 $n2 orient right-down
$ns duplex-link-op $n1 $n2 orient right-up
$ns duplex-link-op $n2 $n3 orient right
$ns duplex-link-op $n3 $n4 orient right-up
$ns duplex-link-op $n3 $n5 orient right-down
#观测n2到n3之间queue的变化,这是要给NAM用的
set tcp [new Agent/TCP]
$ns attach-agent $n0 $tcp
set sink [new Agent/TCPSink]
$ns attach-agent $n5 $sink
$ns connect $tcp $sink
#在NAM中,TCP的联机会以Green表示
$tcp set fid_ 1
#在TCP联机之上建立FTP应用程序
set ftp [new Application/FTP]
$ftp attach-agent $tcp
$ftp set type_ FTP
#建立一条UDP的联机
set udp [new Agent/UDP]
$ns attach-agent $n1 $udp
set null [new Agent/Null]
///
//不要忘记添加这句话,否则运行不了
$ns attach-agent $n3 $null
///
$ns connect $udp $null
#在NAM中,UDP的联机会以红色表示
$udp set fid_ 2
#在UDP联机之上建立CBR应用程序
set cbr [new Application/Traffic/CBR]
$cbr attach-agent $udp
$cbr set type_ CBR
$cbr set packet_size_ 1000
$cbr set rate_ 1mb
$cbr set random_ false
#设定FTP和CBR资料传送开始和结束时间
$ns at 0.1 "$cbr start"
$ns at 1.0 "$ftp start"
$ns at 4.0 "$ftp stop"
$ns at 4.5 "$cbr stop"
#结束TCP的联机(不一定需要写下面的程序代码来实际结束联机)
$ns at 4.5 "$ns detach-agent $n0 $tcp;$ns detach-agent $n3 $sink"
#在仿真环境中,5秒后去呼叫finish来结束仿真(这样要注意仿真环境中的5秒并一定等于实际仿真的时间)
$ns at 5.0 "finish"
#执行仿真
$ns run
接下来是数据分析
- 把测量CBR封包端点到端点间延迟时间的awk程序,写在档案measure-delay.awk档案中。(也就是新建一个.awk文件:
gedit measure-delay.awk
)
#测量CBR封包端点到端点间延迟时间的awk程序
BEGIN {
#程序初始化,设定一变量以记录目前最高处理封包的ID
highest_packet_id = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#记录目前最高的packet ID
if (packet_id > highest_packet_id)
highest_packet_id = packet_id;
#记录封包的传送时间
if (start_time[packet_id] == 0)
start_time[packet_id] = time;
#记录CBR(flow_id = 2)的接收时间
if( flow_id == 2 && action != "d") {
if(action == "r") {
end_time[packet_id] = time;
}
}else {
#把不是flow_id = 2的封包或者是flow_id = 2但此封包被drop的时间设为-1
end_time[packet_id] = -1;
}
}
END {
#当资料列全部读取完后,开始计算有效封包的端点到端点延迟时间
for(packet_id = 0;packet_id <= highest_packet_id;packet_id++)
{
start = start_time[packet_id];
end = end_time[packet_id];
packet_duration = end - start;
#只把接收时间大于传送时间的记录列出来
if(start < end) printf("%f %f\n",start,packet_duration);
}
}
结果如下:会出来好多组数据(这里不全部列出了,大概就是下面这些),用画图软件把这些点画出来会容易看些。
0.100000 0.038706
0.108000 0.038706
0.116000 0.038706
0.868000 0.038706
1.956000 0.038706
1.964000 0.038706
1.972000 0.038706
1.980000 0.038706
2.124000 0.038706
2.508000 0.041529
2.516000 0.038706
2.708000 0.041812
2.884000 0.047647
3.804000 0.076165
3.812000 0.077765
3.820000 0.074471
3.828000 0.076071
4.156000 0.038706
4.164000 0.038706
4.460000 0.038706
4.468000 0.038706
2.jitter延迟时间变化量delay variance
创建文件measure-jitter.awk
#jitter就是延迟时间变化量delay variance
BEGIN {
#程序初始化
old_time = 0;
old_seq_no = 0;
i = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#判断是否为n2传送到n3,且封包型态为cbr,动作为接受封包
if(node_1 == 2 && node_2 == 3 && type == "cbr" && action == "r") {
#求出目前封包的序号和上次成功接收的序号差值
dif = seq_no-old_seq_no;
#处理第一个接收封包
if(dif == 0)
dif = 1;
#求出jitter
jitter[i] = (time-old_time)/dif;
seq[i] = seq_no;
i = i+1;
old_seq_no = seq_no;
old_time = time;
}
}
END {
for(j = 1;j < i;j++)
printf("%d\t%f\n",seq[j],jitter[j]);
}
得出的结果也是一堆数据,有500多个。
488 0.004706
489 0.004706
490 0.004705
491 0.004706
492 0.004706
493 0.004706
494 0.004706
495 0.004706
496 0.004706
497 0.004706
498 0.004706
499 0.004705
500 0.005177
501 0.008000
502 0.008000
503 0.008000
504 0.008000
505 0.008000
506 0.008000
507 0.008000
508 0.008000
509 0.008000
510 0.008000
511 0.008000
512 0.008000
513 0.008000
514 0.008000
515 0.008000
516 0.008000
517 0.008000
518 0.008000
519 0.008000
520 0.008000
521 0.008000
522 0.008000
523 0.008000
524 0.008000
525 0.008000
526 0.008000
527 0.008000
528 0.008000
529 0.008000
530 0.008000
531 0.008000
532 0.008000
533 0.008000
534 0.008000
535 0.008000
536 0.008000
537 0.008000
538 0.008000
539 0.008000
540 0.008000
541 0.008000
542 0.008000
543 0.008000
544 0.008000
545 0.008000
546 0.008000
547 0.008000
548 0.008000
549 0.008000
3.测量CBR Packet Loss的情况写在档案measure-drop.awk内
#把测量CBR Packet Loss的情况写在档案measure-drop.awk内
BEGIN {
#程序初始化,设定一变量记录packet被drop的数目
fsDrops = 0;
numFs = 0;
}
{
action = $1;
time = $2;
node_1 = $3;
node_2 = $4;
type = $5;
flow_id = $8;
node_1_address = $9;
node_2_address = $10;
seq_no = $11;
packet_id = $12;
#统计从n1送出多少packets
if(node_1 == 1 && node_2 == 2 && action == "+")
numFs++;
#统计flow_id为2,且被drop的封包
if(flow_id == 2 && action == "d")
fsDrops++;
}
END {
printf("number of packets sent:%d lost:%d\n",numFs,fsDrops);
}
得出的结果是:number of packets sent:550 lost:14