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 on to the bus, if on e 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_co
#define DISABLE (intrpt_co
#define STOP (intrpt_co
#define PACKET_GENERATE (intrpt_co
//以上定义的是各个状态之间转换的条件。当有中断产生时(确切说,是当OPNET获得离散事件列表中的一个事件时),判断相应的中断码,如果条件成立,则跳转。
op_intrpt_schedule_self(stop_time, SSC_STOP)
---->intrpt_co
数据包产生程序:
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);
注意:要在创建包格式时,设置包相应的域为放置包的域。