基于Tcl语言配置简单网络环境过程解析

1. Tcl脚本文件circle.tcl代码注释

#设定模拟需要的一些属性
set val(chan) Channel/WirelessChannel
set val(prop) Propagation/TwoRayGround
set val(netif) Phy/WirelessPhy
set val(mac) Mac/802_11
#将协议设置为 DSR 后,同时将队列设置为 CMUPriQueue
set val(ifq) CMUPriQueue
set val(ll) LL
set val(ant) Antenna/OmniAntenna
set val(ifqlen) 50
#将节点个数预设为 0,待用户输入。此项要求用户一定输入,否则不执行模拟。
set val(nn) 0
set val(rp) DSR
#场景大小默认值为 1000*1000
set val(x) 1000
set val(y) 1000
#圆的半径缺省值为 400
set val(r) 400
#该过程用于在屏幕上打印在终端输入 ns circle.tcl 后添加参数的格式
proc usage {} {
  global argv0
  puts "\nusage: $argv0 \[-nn nodes\] \[-r r\] \[-x x\] \[-y y\]\n"
  puts "note: \[-nn nodes\] is essential, and the others are optional.\n"
}
#该过程用来根据用户的输入更改一些预设参数的值
proc getval {argc argv} {
  global val
  lappend vallist nn r x y z
  #argc 为参数的个数,argv 为整条参数构成的字符串
  for {set i 0} {$i < $argc} {incr i} {
    #变量 arg 为 argv 的第 i 部分,以空格为分界
    set arg [lindex $argv $i]
    #略过无字符“-”的字符串,一般是用户键入的数字
    #string range $arg m n 表示取字符串$arg 的第 m 个字符到第 n 个字符
    	if {[string range $arg 0 0] != "-"} continue
    set name [string range $arg 1 end]
    #更改预设变量(节点个数,半径,场景大小)
    set val($name) [lindex $argv [expr $i+1]]
  }
}
#调用 getval 过程
getval $argc $argv
#用户没有输入参数,只键入了 ns circle.Tcl,则节点个数认为0
if { $val(nn) == 0 } {
  #打印用法
  usage
  exit
}

#创建模拟实例
set ns [new Simulator]

#设置记录文件
set tracefd [open circle.tr w]
$ns trace-all $tracefd
set namtracefd [open circle.nam w]
$ns namtrace-all-wireless $namtracefd $val(x) $val(y)

#关闭trace文件并调用nam程序演示动画
proc finish { } {
	global ns tracefd namtracefd
	$ns flush-trace
	close $tracefd
	close $namtracefd
	exec nam circle.nam &
	exit 0
}

set topo [new Topography]
$topo load_flatgrid $val(x) $val(y)

create-god $val(nn)
#节点配置。由于版本原因,addressType设为def
$ns node-config -addressType def\
-adhocRouting $val(rp) \
    -llType $val(ll) \
    -macType $val(mac)\
    -ifqType $val(ifq) \
    -ifqLen $val(ifqlen) \
    -antType $val(ant) \
    -propType $val(prop) \
    -phyType $val(netif) \
    -channelType $val(chan) \
    -topoInstance $topo \
    -agenttrace ON \
    -routertrace ON \
    -mactrace OFF \
    -movementtrace OFF

#初始化节点
for {set i 0} {$i < $val(nn)} {incr i} {
#创建节点
set node_($i) [$ns node]
$node_($i) random-motion 0
#计算节点位置并设置,使用三角函数进行计算
	$node_($i) set X_ [expr $val(r) * cos($i * 2 * 3.14159 / $val(nn))]
  $node_($i) set Y_ [expr $val(r) * sin($i * 2 * 3.14159 / $val(nn))]
$node_($i) set Z_ 0
#设置在nam中移动节点显示大小,否则,nam中无法显示节点
	$ns initial_node_pos $node_($i) [expr $val(x) / 10]
}

#在node_(0)节点上建立一个UDP代理
set tcp [new Agent/UDP]
$ns attach-agent $node_(0) $tcp
#在node(0)节点沿直径对面的节点上建立一个数据接收器
set null [new Agent/Null]
$ns attach-agent $node_([expr $val(nn)/2]) $null
#新建CBR流量发生器,分组大小500B,间隔0.05s
set cbr [new Application/Traffic/CBR]
$cbr set packetSize_ 5000
$cbr set interval_ 0.05
#连接UDP和Null
$cbr attach-agent $tcp
$ns connect $tcp $null
#在0.1s时发送数据,3.0s时停止发送数据,5.0s时调用finish过程
$ns at 0.1 "$cbr start"
$ns at 3.0 "$cbr stop"
$ns at 5.0 "finish"
$ns run

2. gawk脚本代码analysis.awk注释

BEGIN {
#设置初始变量
num_D = 0;	#丢包数
num_s = 0;	#发送包数
num_r = 0	;	#收到包数

rate_drop = 0;	#丢包率
sum_delay = 0;	#总延迟时间
average_delay = 0;	#平均延迟时间

}
{
	#读取trace文件记录
	event = $1;	#第一列为包的操作(s为发送包,r为接收包)
	time = $2;	#第二列为操作时间
	node = $3;	#第三列为节点号
	trace_type = $4;	#第四列为操作层
	flag = $5;	#第五列为标志位
	uid = $6;	#第六列为节点标识
	pkt_type = $7;	#第七列为包类型
	pkt_size = $8;	#第八列为包的大小

#操作
	if (event == "s" && trace_type == "AGT" && pkt_type == "cbr")
	{	send_time[uid] = time;	#创建数组记录发包时间
		num_s++;		#记录发送包总数
	}
	if (event == "r" && trace_type == "AGT" && pkt_type =="cbr")
	{	delay[uid] = time - send_time[uid];	#创建数组记录延迟时间
		num_r++;		#记录收到包总数
	}
	if (event == "D" && pkt_type == "cbr")
		delay[uid] = -1;	#-1表示包丢失,该包不会记入延迟时间
}

END {
	#计算丢包数和丢包率
	num_D =num_s-num_r;	#丢包总数
	rate_drop = num_D / num_s * 100.0;	#计算丢包率

	#计算延迟
	for ( i = 0; i < num_s; i++)
		{if (delay[i] >= 0)
			sum_delay += delay[i];
		}#总延迟时间
	average_delay = sum_delay / num_r;	#平均延迟时间

	#打印结果
	printf("number of packets droped: %d \n",num_D);
	printf("number of packets sent: %d \n",num_s);
	printf("drop rate: %.3f%% \n",rate_drop);
	printf("average delay time: %.9f \n",average_delay);
}

3. 实验结果

(1)

  将网络节点数设置为12,运行结果如下,生成了两个记录文件nam文件和trace文件。

此时的trace文件大小为91.8kb,nam文件大小为76.0kb。


接下来通过gawk工具对生成的trace文件进行分析。如果没有安装gawk工具,使用命令sudo apt-get install gawk进行安装。
  结果得到网络模拟过程的丢包数、发包数、丢包率和平均延时。

(2)重新修改节点数为8,运行结果如下,但此时文件夹中并没有新增额外的circle.nam和circle.tr文件。

查看两文件的属性,发现大小发生了改变,说明应该是新建的网络模拟环境的记录文件发生了覆盖。


同样适用gawk对生成的trace文件进行分析。发现随着网络节点数的增加,导致丢包率和平均延时都增加了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Linux虚拟机修改ip地址,查看网关,网络环境配置的教程

    修改虚拟机的ip地址: 进入如下界面,直接修改子网ip即可. 查看网关: Linux网络环境配置: 第一种方式(自动获取): 说明:登陆后,通过界面来设置自动获取ip 我们先进入设置: 把自动连接勾上然后点应用.之后每次启动系统的时候就可以自动连接网络了. 特点:Linux启动后会自动获取ip,缺点是每次自动获取的ip地址可能不一样,这种方法不适用于做服务器,因为我们服务器的ip需要实时固定. 第二种方法:(指定固顶的ip) 说明: 直接修改配置文件来指定ip,并可以链接到外网(程序员推荐),编

  • VMware下Centos7桥接方式网络配置步骤详解

    VMware虚拟机下Centos7 桥接方式网络配置完整步骤,供大家参考,具体内容如下 一.打开虚拟机的设置页面,设置虚拟机桥接模式如图:选择桥接模式(复制物理网络连接可选) 二.桥接模式配置VMware虚拟机网络 1. 查看宿主机网络信息: ipconfig /all 以太网适配器 本地连接: 连接特定的 DNS 后缀 . . . . . . . : 描述. . . . . . . . . . . . . . . : Realtek PCIe GBE Family Controller 物理地

  • VMware虚拟机下的CentOS7网络配置(主机无线上网)

    首次使用CentOS7系统,在做网络配置时遇到不少问题.特写此博客,记录问题的解决方法,欢迎各位大佬指正. 一.虚拟机设置 VMware界面最上面,选择虚拟机->设置:将网络连接改为桥接模式,如下图所示: 二.查看主机DNS地址 win+R 输入cmd,启动命令行界面,输入ipconfig/all,查看主机DNS服务器地址,如下图所示: 注意,由于本机是无线上网,此处为无线局域网的DNS服务器地址,记下此地址,后面有用. 三.修改CentOS7网络配置文件 1.在CentOS7中打开终端,输入

  • VMWare虚拟机15.X局域网网络配置教程图解

    最近在搞几台虚拟机来学习分布式和大数据的相关技术,首先先要把虚拟机搞起来,搞起虚拟机第一步先安装系统,接着配置网络 vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式).NAT(网络地址转换模式).Host-Only(仅主机模式). 一.Bridged(桥接模式) 桥接模式相当于虚拟机和主机在同一个真实网段,VMWare充当一个集线器功能(一根网线连到主机相连的路由器上),所以如果电脑换了内网,静态分配的ip要更改.图如下: 二.NAT(网络地址转换模式) NAT模式

  • Docker 默认bridge网络中配置DNS的方法

    本节描述如何在Docker默认网桥中配置容器DNS. 当您安装Docker时,就会自动创建一个名为bridge 的桥接网络. 注意 : Docker网络功能允许您创建除默认网桥之外的用户自定义网络. 有关用户自定义网络中DNS配置的更多信息,请参阅Docker嵌入式DNS部分. Docker如何为每个容器提供主机名和DNS配置,而无需在构建自定义Docker镜像时在内部写入主机名?它的诀窍是利用可以写入新信息的虚拟文件,在容器内覆盖三个关键的/etc 文件. 你可以通过在一个容器中运行mount

  • linux网络NAT配置方式详解

    本文为大家分享了linux网络NAT配置方式,供大家参考,具体内容如下 NAT访问的权限如下: 外网不可以访问虚拟机,主机和虚拟机可以互访,网络和主机也可以互访: 1.打开虚拟机--编辑--虚拟网络编辑器--. 2. 3.进入虚拟机的linux系统点击网络 4. 5.点击ipv4 6.配置虚拟机的ip ip地址前三位要和网关前三位保持一致 子网掩码都是一样的 网关要和虚拟机编辑器的网关保持一致 6.1.查看网关 7.打开本地网络连接--更改适配器--找到vMware8 有的可能不一样 把鼠标放上

  • 虚拟机中Linux新手入门配置IP以及重启网络

    刚刚接触虚拟机,或者刚在虚拟机中安装linux的朋友们,因为是在虚拟机中安装的系统,所以需要自己配置IP地址. 下面分几步来配置这个IP地址: 第一步:打开你的虚拟机,打开linux,并使用root账号登录. 如图,我是用的是CentOS7.2系统,点击登录进去后,进入敲指令的界面,输入vi /etc/sysconfig/network-scripts/ifcfg-eth0(后面的eth每台电脑不一样,可按tab键补全.) 按照上述指令进入配置IP的界面,如图所示 由于我是已经配好的了,所以会比

  • CentOS8.0 网络配置的实现

    一.CentOS 7和CentOS 8网络配置区别: VMware Workstation 15 Pro中安装了CentOS 8.0.1905,但在配置IP地址过程中发现没有了network.service,并且/etc/sysconfig/network-scripts目录中也没有任何脚本文件,CentOS 7中同时支持network.service和NetworkManager.service(简称NM)2种方式配置网络,而在CentOS 8中已经废弃network.service,必须通过

  • 基于Tcl语言配置简单网络环境过程解析

    1. Tcl脚本文件circle.tcl代码注释 #设定模拟需要的一些属性 set val(chan) Channel/WirelessChannel set val(prop) Propagation/TwoRayGround set val(netif) Phy/WirelessPhy set val(mac) Mac/802_11 #将协议设置为 DSR 后,同时将队列设置为 CMUPriQueue set val(ifq) CMUPriQueue set val(ll) LL set v

  • Spring Boot2配置服务器访问日志过程解析

    这篇文章主要介绍了Spring Boot2配置服务器访问日志过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Tomcat控制台中看到的日志是服务器的日志,而服务器访问日志则是记录服务处理的请求信息. 开发环境:IntelliJ IDEA 2019.2.2 Spring Boot版本:2.1.8 1.新建一个名称为demo的Spring Boot项目. 2.application.yml 添加配置 server: tomcat: base

  • 基于spring security实现登录注销功能过程解析

    这篇文章主要介绍了基于spring security实现登录注销功能过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependenc

  • Django项目基础配置和基本使用过程解析

    这篇文章主要介绍了Django项目基础配置和基本使用过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 在需要的目录下创建Django项目输入命令:django-admin startproject 项目名称 创建完成后在pycharm下Terminal中输入命令:Python manege.py startapp app名称 (新建Django的APP项目) 一.Django的相关配置 Django项目 setting 配置: 1.tem

  • VSCode IDE 配置环境过程解析

    目录 说明 前提条件 创建项目 导出模板项目 VSCode创建项目 配置C/CPP环境 配置编译任务 如果用 PlatformIO 创建 libopencm3 项目可以做到零配置, 只是 libopencm3 的版本会旧一点. 这里说的是仅使用 VSCode 创建C/CPP项目时的配置. VSCode 有代码提示, 定位来源和各种快捷键, 更适合日常编码工作. 说明 因为 PlatformIO 的 platform:st-stm32 自带 libopencm3, 如果用 PlatformIO 创

  • 基于C语言实现简单五子棋游戏

    本文实例为大家分享了C语言实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 五子棋大家都玩儿过,所以规则就不介绍了 今天遇到一个学弟在实现的时候遇到一些问题,所以将实现的过程记录下 水平有限,仅供参考,互相交流,共同进步. #include<stdio.h> #include<windows.h>   int main() {       int i,j;//表示棋盘横纵坐标     /*********************************************

  • 基于C语言实现简单的走迷宫游戏

    本文实例讲述了C语言实现简单的走迷宫游戏的方法,代码完整,便于读者理解. 学数据结构时用"栈"写的一个走迷宫程序,实际上用到双向队列,方便在运行完毕后输出经过的点. #include <cstdio> #include <deque> #include <windows.h> using namespace std; class node { public: int x,y; int lastOpt; }; deque<node> sta

  • 在Mac中PyCharm配置python Anaconda环境过程图解

    在 python 开发中我们最常用的IDE就是PyCharm,有关PyCharm的优点这里就不在赘述.在项目开发中我们经常用到许多第三方库,用的最多的命令就是pip install 第三方库名 进行安装.现在你可以使用一个工具来帮你解决经常安装第三方库的麻烦,这个工具就是Anaconda. Anaconda集成了100多个常用的第三方库,在项目的开发中就可以减少使用 pip 命令进行安装.有关Anaconda的安装包,大家可以前往官网进行下载并安装. 这里我想注重说明的是Mac 中PyCharm

  • 基于C语言实现简单的扫雷小游戏

    本文实例为大家分享了C语言实现简单的扫雷小游戏的具体代码,供大家参考,具体内容如下 首先来规划一下扫雷游戏实现的几个步骤: 初始化棋盘:二维数组的遍历及赋值 为了后续代码的简洁方便,我们用'0'来初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++

  • 基于C语言实现简单学生成绩管理系统

    本文实例为大家分享了C语言实现简单学生成绩管理系统的具体代码,供大家参考,具体内容如下 一.系统主要功能 1.密码登录2.输入数据3.查询成绩4.修改成绩5.输出所有学生成绩6.退出系统 二.代码实现 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 10 struct student {     char num[10];     char name[20];     int ol

随机推荐