opnet總結

下面總結一下自己在使用opnet開發仿真平臺過程中遇到的問題。有的問題是學習軟件初期遇到的,有的是在開發過程中花費幾天時間才解決的問題。現在回頭來看,多數已經不是問題,但有的仍需要留心,現以星號標記其程度。

** 1.access和get

但凡涉及到access的函數都是以指針的形式訪問其指向的區域,調用後不會更改指向區域的內容,如op_pk_nfd_access(),op_prg_list_access() ...

涉及到get和remove的函數會將內存中的內容取出,如op_ok_nfd_get(),op_prg_list_remove(),prg_bin_hash_table_item_remove() ...

但也有例外情況,如獲取包流ici的函數op_pk_ici_get(),獲取後相應的ici還附着在包上,只有調用op_pk_ici_destroy()或者重新install一下才會將原來的刪除或覆蓋。

* 2.ici的使用

根據網絡協議的分層原則,低層協議通常是不會讀取高層數據包中的內容,只是做一下封裝。opnet中上下層交互的信令通常用ici來傳遞,即用ici來模擬層間原語。

我一般是分三步走:op_ici_create() -> op_ici_attr_set() -> op_pk_ici_set(),這樣就會爲每個包安裝ici

在計算包大小以及goodput過程中,ici的尺寸是不會考慮在內的。

* 3.調試過程中的多條件跳轉報錯

<<< Program Abort >>>
Multiple true transitions from state (idle)

問題原因:在對應的進行模型中同一時刻滿足條件的狀態跳轉多於一個。

* 4.包域的問題

在包的編輯器中,包“域”的數據類型給定的有: integer, floating point, structure, packet, information, integer(64 bit), packet ID, or object ID,用這些類型來模擬每一冊協議單元的字段或數據域。

我經常使用的是integer,struct和packet。其中的struct類型需要在頭部定義一個結構體類型的數據,代表整個"域"(通常作爲頭部),packet一般採取inherited上層包的形式,作爲數據域。注意struct域可以設置大小,但是該大小與你定義的結構體實際內存佔用情況無關,只是代表協議設計中該包域的大小,不會影響程序運行,只會影響統計結果的收集。

*** 5.慎用op_pk_send_forced()函數

該函數對應的是強制無延遲的發包策略。自己多次在仿真中都出現如下問題:

<<< Recoverable Error >>>
Unable to execute intrpt at process (2)
Process is already within an invocation

當時並無頭緒如何解決這個問題,很幸運的是,在碰巧將op_pk_send_forced()函數改成op_pk_send()後問題消失了。就如同Product Documention函數中警示的那樣,op_pk_send_forced()函數在多進程交互過程中會導致不可預期的結果。

* 6.包的分片和重組

在設計過程中,由於底層協議幀大小的限制通常要對上層的數據包分片,這就需要使用分段緩衝區。緩衝區的創建使用函數op_sar_buf_create(),該函數有兩個參數:第一個參數中對應了多個常量標識符,我用到的有兩個,OPC_SAR_BUF_TYPE_SEGMENT(對應分段緩衝區)和OPC_SAR_BUF_TYPE_REASSEMBLY(對應重組緩衝區),其中分段緩衝區分段後的數據還可以接着繼續被分段。第二個參數也對應了多個常量標識,在分段時我用到的也是有兩個,OPC_SAR_BUF_OPT_PK_BNDRY(不將分段打包成固定大小)和OPC_SAR_BUF_OPT_SEG_PAD(將數據打包成固定大小),在重組時用到的爲默認參數OPC_SAR_BUF_OPT_DEFAULT。

** 7.結構體的設置與獲取

get(獲取)信息的時候都要取地址,如op_ici_attr_get(recv_high_iciptr, "node_id", & nid_info_get); op_pk_nfd_access (pkptr, "head block", & hb_ptr);
set(設置)的時候不用,如op_pk_nfd_set (bd_pkptr, "head block", hb_ptr, op_prg_mem_copy_create, op_prg_mem_free, sizeof (head_block)); op_ici_attr_set (iciptr, "node_id", nid_info);

* 8.關於全局和局部統計量

全局統計量(global)能夠統計場景中總共收到的數據包個數,本地統計量(local)能夠統計每個節點收到的數據包。在設置好統計量後將其提升到模塊屬性,方便選擇。

**** 9.opent自動崩潰的問題

暑假回來繼續使用opent,軟件隔一段時間(幾分鐘)就會崩潰並自動關閉,出現如下問題:

unhandled vex exception
consult C:\Users\Infonet\op_admin\err_log for more details.
In OPNET,access the information for Help>Error Log>Open.

開始百思不得其解,然後嘗試清理電腦中的垃圾,發現不知道在什麼時候無意裝了麥咖啡殺毒(一向只用360的),卸載後正常了。。一些殺毒軟件也許與opnet不兼容。

** 10.三種進程間內存共享方式(就不自己總結了,轉個別人寫的)

 a)module memory同模塊共享內存:
    通過函數op_pro_modmem_install()和op_pro_modmem_access()訪問。爲了保證process間通信機制,各個 process應當遵循shared memory的數據類型,這就要求process都要知道,因而shared memory的數據結構定義應當房子外部定義".h"文件中,幷包含在每個process的header block中。shared memory一開始是沒有的,是由process來決定什麼時候分配以及分配多大,這些通過op_pro_modmem_access()來完成。內存的分配一般是通過op_prg_meme_alloc()來完成。
    b)父子共享內存:
    只有以父子關係聯繫在一起的process才能訪問的私有共享內存。這種共享內存只能在child process由op_pro_create()產生時由op_prg_mem_alloc()分配,且不能被替換。通過 op_pro_parmem_access()訪問。通過op_pro_invoke()通知對方對共享內存的內容進行的修改和,以及對內容的檢查。
    c)參數內存(argument memory)
    將內存地址作爲op_pro_invoke()的參數傳給別的進程用以通信,通過op_pro_argmem_access()來完成訪問。與前兩個不同的是,這部分內存不是永恆的。

**** 11.關於不同進程使用同一個struct的問題

不同模塊間的struct中的元素必須按照相同的順序定義,否則不但不會報錯,而且會導致讀取其中元素數值的錯誤

解決方法:將多次使用的struct放在頭文件中,每個使用該struct的進程包含一下該頭文件即可。

*** 12.最後記錄幾個錯誤記錄
op_ev_cancel (ack_event); //可能取消不了,因爲中斷已結束!!需要加測試條件 if( op_ev_pending (ack_event) == OPC_TRUE) 判斷當前事件是否還存在。

list中的包發送以後就不能再發了,即使是access,也不行。

兩個list不能直接賦值,要先creat,再init,再copy

爲了使進程同步,在父進程的init狀態就要invoke一下子進程



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章