opnet物联网仿真2.5 陈敏 包交换网络全解----修正版

首先我们搭建包格式 packet_format

首先这里就是一个大坑,陈敏这本书里面有明显错误,在他2006年的那本书里面,他用的是32位(4字节)的包,但是这本书里面他建议使用4位的包,这里是大错,因为在后面我们会用到一个写32位的函数,这里是第一个坑

这里还是建议使用32位的陈敏2004/2006版的书里面的包格式

然后我们开始搭建链路模型,这里可以完全按照陈敏书里面来,请注意我的截图,这里我的链路错误用的是error_zero_err

下面我们就能搭建节点的node模型,这里我们在陈敏那本2006年的书里面写的是4个节点,这里我们用了8个节点,不过node的模型是一样的,但是hub的模型不一样。

不一样

请注意了,我们这里一定要更改收发机channel属性,来匹配我们的链路

当然还有src模块的更改,我们要把src模块变成一个产生包的一个模块,所以要这么改

这里我们注意了,除了你要改包格式之外,我们要把packet interarrival time这个东西提升属性变成promoted,什么叫提升属性,也就是你仿真的时候可以指定这个属性值为多个值,这样的话你就能够进行仿真对比

这里我们包交换网络就是要考察包生成速率不同的时候,信道利用率怎么样,所以要把它提升属性

然后我们跳到node interfaces界面,去更改我们的一些界面属性,按照陈敏他的教程,我们这里可以重命名那个interarrival time,然后哦我们对此做出初值进行修改,这里建议看书

下面是hub的模型,同样我们要更改收发机的channel属性,这里我就不放截图了,反而这里其实比较简单,注意收发信机不要配错了,我有一次没有用固定节点,用的可变节点,结果就一直出不来结果2333.

下面我们就能配两个进程模型了,分别是hub的和node的

我们先看hub的,这里我们必须明确一下opnet进程模型的一些概念,PK_ARRVL这种就是条件,而route_pk()是满足这个条件触发的函数,而触发函数之后,转移到的状态仍然是idle,我们这里idle的状态是红的,也就是所谓的非强制,也就说,进程在这个状态是可以中断的!!!这个非常重要,我们进程状态转换就是牵扯到这种概念

 我们进入FB模块看一下我们的代码

static void route_pk(void)
{
       int dest_address;
    Packet* pkptr;
    FIN(route_pk());
    pkptr = op_pk_get(op_intrpt_strm());//从中断流编号之中找到包的指针
    op_pk_nfd_get(pkptr,"dest_address",&dest_address);//找到包的目的地址
    op_pk_send(pkptr,dest_address);//转发到目标流中
    FOUT;
}

建议看一下陈敏2015版物联网仿真的第二章,熟读,里面的代码你就明白了,这里就是一个简单的提取目标地址然后转发的代码。

然后我们进入HB看一下我们对于PK_ARRVL的定义

#define PK_ARRVL (op_intrpt_type()==OPC_INTRPT_STRM)

显然,我们只要认为中断是流中断的时候,我们就说,有包流到达了,这样我们要转发,这是显而易见的,但是还是建议先读一下书,看一下中断的概念

然后我们到了node模块的代码,node模块中我们要干什么?就是node是一个双工的模块,我们既要产生包把它送出去,又要接受从hub转发来的包,所以说让我们先看一下代码和有限状态机

看我们的有限状态机,这里我们看init状态,变成了绿色,这就是所谓的强制状态,也就是说,我们这个状态是绝对不会中断的,进程绝对不会停留在强制状态,一定要让他顺序执行,所以说,强制状态我们一般不写出口代码,因为本质上他的进口代码和出口代码应该是一样的。

我们先看看init的进口代码里面写了什么东西

address_dist = op_dist_load("uniform_int",0,7);//产生随机分布,应该是平均分布的0-7
ete_gsh = op_stat_reg("ETE Delay",OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);//得到统计量的句柄

这里又有坑了。数据包没有创建。随机数没有写到包里面。

Packet* pkptr;


int num =0;

pkptr =op_pk_create_fmt("IOT_Simulation_pksw_format");
address_dist=op_dist_load("uniform_int",0,7);


op_pk_nfd_set_int32(pkptr,"dest_address",num);


ete_gsh=op_stat_reg("ETE Delay",OPC_STAT_INDEX_NONE,OPC_STAT_GLOBAL);

op_pk_send(pkptr,XMT_OUT_STRM);

这时候我们奇怪了,我们并没有定义address_dist和ete_gsh啊,但是很简单,这两个东西定义在SV(状态变量)里面

我们进入SV看一看状态变量的定义,请注意,状态变量就是相当于这个模型自己拥有的变量,所以我们在SV里面定义了一遍,然后就不用再定义了

首秀按我们要知道Distriction*这个东西是一个函数指针,他指向一个随机分布函数,请注意,我们这里陈敏书里又有一个错误,也就是他的随机分布是0-3,事实上这是他2004年那本书里面写的,在2015版这本书里面应该使用0-7对应我们的八个收发信机

而stathandle指向我们的统计量,请注意,我们的统计量应该是全局统计量,但是这个全局统计量我们需要先声明一下(这里,ETE delay代表每一个包的输入到输出的延迟,也就是transmission delay(我们前面忽略了传播时延,只计入传输时延),自然这应该是一个全局变量,毕竟我们要统计全局的包的delay)

终于,我们可以看一下我们的HB的定义和FB里面的函数了,这里建议一定要理解陈敏那本书的第二章

让我们看看HB里面写了什么

#define RCV_IN_STRM 0 
#define SRC_IN_STRM 1 
#define XMT_OUT_STRM 0 

#define SRC_ARRVL (op_intrpt_type () == OPC_INTRPT_STRM && op_intrpt_strm () == SRC_IN_STRM) 
#define RCV_ARRVL (op_intrpt_type () == OPC_INTRPT_STRM && op_intrpt_strm () == RCV_IN_STRM)

什么意思,这里我们定义输入的包流0代表RCV,也就是从hub输入进来的,而输入包流1代表SRC,表示这个node他自己产生的包流

而输出包流显然只有一个,那么我们直接编号0就行,代表输出出去的包流

而SRC_ARRVL要求是流中断,而且中断号应该就是1

RCV_ARRVL要求是流中断,中断号显然就是0

这里就好解释了,然后我们进入最重要的FB里面,看一下我们的核心函数

static void xmt(void)
    {
        Packet* pkptr;
        FIN(xmt());
        pkptr = op_pk_get(SRC_IN_STRM);//根据包流编号得到包,这种包应该是src产生的包
        op_pk_nfd_set_int32(pkptr,"dest_address",(int)op_dist_outcome(address_dist));//填入dest_address
        op_pk_send(pkptr,XMT_OUT_STRM);//输出,输出包流号为0
        FOUT;
    }

static void rcv(void)
    {
        Packet* pkptr;
        double ete_delay;
        FIN(rcv());
        pkptr = op_pk_get(RCV_IN_STRM);//根据包流编号得到包,这种包是hub转发的包
        ete_delay = op_sim_time()-op_pk_creation_time_get(pkptr);//计算时延
        op_stat_write(ete_gsh,ete_delay);//填入ete_gsh所指代的时延,也就是全局变量ETE Delay
        op_pk_destroy(pkptr);//释放内存
        FOUT;
    }

我在里面还是添加了一些注释,应该能够帮助理解,但是具体请一定要参考陈敏的书,其实理解起来很简单

每一个node都是两种作用,产生包把它发出去,或者接受从hub转发过来的包,这里我说道了之前说的陈敏这本书里面的坑

也就是这里op_pk_nfd_set_int32这个函数本应该是写一个32位的数据,如果你在第一步设置包格式的时候写了4位必定出大错

最后我们一定要激活仿真中断,这在前一个进程模型(hub那一步)也要做的,所以两个模型都用这一步

注意把begsm intrpt改成enabled

好了,现在我们只要把两个进程模型编译一下,然后edit attribute把它们放进该有的模块里面就行了

最后,我们终于可以进行网络层的建模了,而这里面也有大坑,稍后会提到

我们new一个project出来,按照陈敏那本书的指示,在你的所有模型里面就能用到这样的集合

按照如图所示摆好

也就是一个hub,8个node

好了,现在我们点ctrl + L,或者在拓扑里面点verify links,检查我们的链路是否合理

本人在暑假里面做的四交换的网络很快就合理,但是这一次8交换的网络,一开始都是failed,链路居然连不上,请注意,这里是一个大坑,因为正常来说如果你的格式设置正确的话,opnet可能会根据你链接的顺序自动找收发信机,但如果你摆的顺序不是那么准确的话,请手动设置,这里我卡了半天,这也是陈敏这本书里面没有提到的,注意,我们右击每一个链路

这样

点edit attributes,这样设置

如果你的链路失败,很可能是你的收发信道都是none,注意手动设置

这样,我们的拓扑就搭好了,最后就是仿真了,找到

进入configure run(advanced)进入仿真页面,我们最重要的是设置之前我们promoted的那个interarrival time

这里我们两个仿真,一个设置的4,一个是40

在你run之前先设置一下你要记录的仿真量

最后,run吧

得到结果,我们终于完成了这个包交换网络

其实我们这里一个是ete delay(端到端的时延),其实这时延的表示还不够精确,如果我们用离散图,就可以看到每一个包的时延了,还有一个是信道利用率,显然,单位时间内发包越多,信道利用率肯定越大。

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值