• OPNET学习笔记之ICI


      在OPNET中,可以使用ICI来进行进程之间的数据传递,所谓的ICI就是Interface Control Information(接口控制信息),它是一种特殊的数据结构,类似与C语言中的结构体,格式可以用ICI Editor进行定义。在《OPNET仿真建模大解密》中说ICI应用场合有(1)模拟层间原语,就是网络各层次之间传递的不包含在数据包内的信息,如物理层单元数据指示(包含是否TDC,是否加扰等)。(2)模拟进程交互中的消息。
    //----------------------------------------------------------------以下来自OPNET帮助文档

      仿真核心通过“绑定(installation)”机制将一个ICI与事件关联,每一个进程(processor可以有多个进程)在任意时刻只能绑定一个ICI。当进程创建时默认没有ICI绑定,通过调用KP op_ici_install()来实现绑定(需要先通过op_ici_create创建一个ICI),然后仿真核心会自动将该进程产生的事件同该ICI关联,也可以是subsequent events。事实上,该ICI地址会一直同该进程产生的所有事件关联,直到被另一个ICI替换为止,为避免ICI与事件间不必要的关联,可以在事件调度结束后重置ICI(就是绑定空ICI,即op_ici_install(OPC_NIL))。但是事实上只要在接收进程不处理ICI,那不必要的关联也不会带来什么损失。

      ICI是动态的,必须由进程创建,KP op_ici_create()返回ICI地址,之后的操作都通过该地址进行。

      关于ICI最重要的操作包括创建,销毁,绑定,这些决定了何时ICI与事件关联,中间还包括其它操作,如更改和提取信息。注意由于ICI并没有严格限制归哪个进程所有,所以就像包,任何进程只要能得到ICI地址,就可以进行这些操作。例如,ICI可以被创建进程销毁,也可以被接收进程销毁,类似的多个进程可以同时修改ICI,而这些修改对所有进程可见

      仿真核心对ICI的操作流程没有严格的限制,但是不用的ICI应被销毁,以避免进程间不必要的复杂的交互。ICI的生存期可以分成两种:

    (一)每次使用,创建并绑定

    1,源进程创建ICI,op_ici_create()

    2,源进程保存信息到ICI,op_ici_attr_set_***()

    3,源进程绑定ICI,op_ici_install()

    4,源进程产生事件(发送包/自中断……)

    5,当事件发生并导致中断时,被中断的进程获得ICI,op_intrpt_ici()

    6,被中断进程获得信息,op_ici_attr_get_***()

    7,被中断进程销毁ICI,op_ici_destroy(),结束。

      注意这种每次使用创建的ICI,源进程在产生事件后不应操作ICI了,取得信息及销毁ICI的工作由目的进程处理。

    (二)永久的ICI

      在某些情况,上一种ICI会导致一系列的对同种ICI的创建、销毁操作,这时更简单的方案是创建ICI一次并不销毁。源进程只需要每次更新ICI的信息并绑定(绑定操作是需要的,因为源进程可能使用多个ICI),然后产生事件。这时对ICI的操作过程如下:

    1,

    1,源进程在初始化时创建ICI(也可以是其它时候,但是只创建一次),op_ici_create()

    2,源进程保存信息到ICI,op_ici_attr_set_***()

    3,源进程绑定ICI,op_ici_install()

    4,源进程产生事件(发送包/自中断……)

    5,当事件发生并导致中断时,被中断的进程获得ICI,op_intrpt_ici()

    6,被中断进程获得信息,op_ici_attr_get_***()

    不需要销毁,结束。

    //--------------------------------------------------------------------------------------

    具体操作,转载自http://hi.baidu.com/freshairjhl/item/888e5e0f437e57113a53eef3

    ICI的使用上,大致可以分为如下几步:

           1.定义你需要的ICI格式,方法是用ICI Editor来编辑。比如我们编辑一个如下格式的ICI,字段名称 field1 ,数据类型int ,默认值 0。我们将这ICI格式的名称保存为test_ici_fmt。
           2.在程序中你需要的地方定义一个ICI指针,如 Ici* iciptr;
           3.创建一个ici,iciptr=op_ici_create("test_ici_fmt")。
           4.给ici中的字段赋值,可以根据需要进行。方法:op_ici_attr_set(iciptr,"field1",1),就是把指针iciptr所指向的那个ici数据的field1字段赋值为1。
           5.用op_ici_install()把你定义的ici绑定到一个输出中断,注意在任何时间仅有一个ici可以绑定到一个中断。绑定之后,你的ici就可以随着这个输出的包发送函数或其他的发送函数输出到另外的进程(模型中的其他层)。
          6.然后,就可以在接收到的层里面获取ici里面的值了,所用的函数是op_ici_attr_get()。在接收之前你需要定义一个与你想获得的字段类型一致的变量,用来保存数值。如,前面我们定义的field1是int型的,我们就需要在接收的层里定义 int   rec1。接收是这样op_ici_attr_get(iciptr,"field1",&rec1)。
         7.Over

    //-------------------------------------------------------------------------------举例,以arp模块为例,进程模型为ip_arp_v4,版本14.5

    //(一)INIT状态的入口代码,创建了一个永久的ICI:

    /* Create an ICI to communicate with data link layer. */
    mac_iciptr = op_ici_create ("ip_mac_req");  //注意该ICI指针在state variable中声明
    //随后在arp_packet_send()函数中设置ICI信息:

    op_ici_attr_set_int32 (mac_iciptr, "protocol_type", NET_PROT_IP);

    //绑定该ICI:

    op_ici_install (mac_iciptr);

    /* Send the packet coupled with the ICI. 也就是产生事件*/

     op_pk_send_forced (pkptr, strm_index);

    /* Deinstall the ICI. 马上取消绑定*/
    op_ici_install (OPC_NIL);

    //最后在mac层的ethernet_mac_llc_pk_accept()函数,即处理来自上层的数据包函数中,在获取ICI信息后没有销毁。

    //(二)临时ICI,在arp_ip_packet_from_mac_handle()函数中:ip_iciptr,注意该ICI指针在函数体内声明

    操作类似,但是在IP模块的ip_dispatch_strm_intrpt_handle()函数中会销毁包携带的ICI信息。

    //------------------------------------------------------------------------------------------------------------------------

  • 相关阅读:
    楷书四大家
    什么叫同学?
    css悬浮在页面顶端
    jq给页面添加覆盖层遮罩的实例
    jQuery实现遮罩层
    jQuery实现的文字逐行向上间歇滚动效果示例
    jquery实现文字由下到上循环滚动的实例代码
    Js/Jquery获取网页屏幕可见区域高度
    本机无法访问虚拟机配置的域名
    thinkphp5+GatewayWorker+Workerman
  • 原文地址:https://www.cnblogs.com/loopever/p/2654100.html
Copyright © 2020-2023  润新知