1、兩種發送packet的方式:
一種是使用主動的,也就是A要發packet給B的時候直接用op_pk_send()(或者加上時延、forced等)。那麼在B就會收到一個OPC_INITRPT_STRM中斷,B響應這個流中斷時就把packet取出來。
一種是被動的,就是A不主動給B發packet,因爲B可能還沒準備好接收。那麼等B準備好接收後就通過op_strm_access()告訴A我準備好了,要packet。op_strm_access()產生一個OPC_INTRPT_ACCESS中斷。A響應這個access
intrpt才把packet發給B。這時候用op_pk_send_quiet()來發送,就不會給B一個strm
intrpt。那麼B如何知道packet什麼時候到來呢?因爲是B自己要求發packet的,那麼它已經做好了接收packet的準備,在它響應下一個中斷的時候可以用op_strm_empty()來判斷是否有pacekt來了。
舉個例子如下
a、源端:
if (!op_subq_empty (0))
{
/* access the first packet in the subqueue */
pkptr = op_subq_pk_remove (0, OPC_QPOS_HEAD);
/* forward it to the destination */
/* without causing a stream interrupt */
op_pk_send_quiet (pkptr, 0);
}
b、目的端:
alloc_instrms = op_strm_max_index_in ();
/* loop through each allocated stream */
for (i = 0; i <= alloc_intstrms; i++)
{
/* if an input stream is connected, and... */
if (op_strm_connected (OPC_STRM_IN, i) == OPC_TRUE)
{
/* if an input stream is connected, access a packet from the source module. */
op_strm_access (i);
/* Collect and forward the packet onto the bus, if one was obtained. */
if (op_strm_empty (i) == OPC_FALSE)
op_pk_send (op_pk_get (i), OUTSTRM_BUS);
}
}
2、分析一個模塊-simple_source的頭文件:
#define SSC_START 0 //數據包開始時間到
#define SSC_GENERATE 1 //數據包產生定時到
#define SSC_STOP 2 //數據包產生結束時間到
//以上定義了各種定時中斷的代碼,當調用op_intrpt_schedule_self()設置一個定時中斷的時候,會返回相應的中斷代碼,以便程序可以正確執行相應的操作。
#define START (intrpt_code==SCR_START) //從初始化轉向數據包產生的狀態
#define DISABLE (intrpt_code==SSC_STOP) //從數據包產生轉向停止
#define STOP (intrpt_code==SSC_STOP) //從初始化轉向停止
#define PACKET_GENERATE (intrpt_code==SSC_GENERATE) //繼續執行數據包產生的狀態
//以上定義的是各個狀態之間轉換的條件。當有中斷產生時(確切說,是當OPNET獲得離散事件列表中的一個事件時),判斷相應的中斷碼,如果條件成立,則跳轉。
op_intrpt_schedule_self(stop_time, SSC_STOP)
---->intrpt_code = op_intrpt_code()獲得中斷代碼SSC_STOP。
數據包產生程序:
next_intarr_time = oms_dist_outcome(interarrival_dist_ptr); //計算下一個數據包產生時間
next_pk_evh = op_intrpt_schedule_self(op_sim_time() + next_intarr_time, SSC_GENERATE);
3、ON/OFF模型下:
平均數據總負載=(業務結束時間-業務開始時間)×平均ON的持續時間
/ (平均ON的持續時間+平均OFF的持續時間)×包長度均值
/ 包到達間隔均值
4、封裝和解封裝
a、封裝
Packet* pbb_pkptr;
Packet* pkptr;
int mac;
mac=10;
pbb_pkptr=op_pk_create_fmt(format1_name);
pkptr =op_pk_create_fmt(format2_name);
op_pk_nfd_set(pkptr,"da",mac);
op_pk_nfd_set(pbb_pkptr,"payload",pkptr);
b、解封裝
Packet* pbb_pkptr;
Packet* pkptr;
int mac;
pbb_pkptr=op_pk_get(op_intrpt_strm());
op_pk_nfd_get(pbb_pkptr,"payload",&pkptr);
op_pk_nfd_get(pkptr,"da",&mac);
注意:要在創建包格式時,設置包相應的域爲放置包的域。