本文是在前3篇关于OPNET的文章基础上进行的,省略及不清楚的部分请参考前文。
本文实现的功能是建立多端口通信所需的端口表。
1.网络模型
一个发送节点0四个接收节点1、2、3、4,如图所示。
2.链路模型
链路模型为单工。
3.节点模型
3.1发送节点模型
如图所示。
3.2接收节点模型
如图所示。
4.进程模型
4.1发送节点
本文只获取这一个发送节点的端口表。
【SV】状态变量,如图所示。
【TV】临时变量:
int i;
int j;
int dest_id;
int assoc_link_id;
char *a1=NULL;
char a[50]={0};
【HB】中代码:
#include
#define SEND1 (op_intrpt_type()==OPC_INTRPT_SELF&&op_intrpt_code()==0)//从四个端口发送数据,则有四个中断
#define SEND2 (op_intrpt_type()==OPC_INTRPT_SELF&&op_intrpt_code()==1)
#define SEND3 (op_intrpt_type()==OPC_INTRPT_SELF&&op_intrpt_code()==2)
#define SEND4 (op_intrpt_type()==OPC_INTRPT_SELF&&op_intrpt_code()==3)
#include
struct table_{
int dest_address;//目的地址
int port;//端口号
};//端口表中的一项,结构体类型
typedef struct peer_type_{
struct table_ table[4];
int length;
}peer_type;//定义一种新的端口表类型,是个结构体,包含端口表项数组和长度
【FB】中代码:
static void get_first_node_name(int link_id)//获取链路两端第一个节点的名称
{
char link_name[50];
char *p=NULL;
FIN(get_first_node_name(link_id));//输入是链路号
op_ima_obj_attr_get(link_id,"name",&link_name);//以链路号获得链路的名称,如“0 -> 1”
p = strtok(link_name," ");//分割字符串并获得第一个空格前的字符串赋值给link_name
sprintf(first_node_name,"%s",link_name);
FOUT;
}
static void get_second_node_name(int link_id)
{
char link_name[50];
char *p=NULL;
FIN(get_first_node_name(link_id));
op_ima_obj_attr_get(link_id,"name",&link_name);
p = strtok(link_name," ");//可以详细参考strtok函数的用法
p = strtok(NULL," ");
p = strtok(NULL," ");
sprintf(second_node_name,"%s",p);
FOUT;
}
初始状态st_0中的代码,如图所示。
在这里首先通过op_topo_assoc_count函数获得和父节点单工链路相连接的节点的数量,注意单工参数为OPC_OBJTYPE_LKSIMP,如果是双工的话需要修改。这里数量为4.
然后是对4个邻居节点进行for循环。
先找到一个邻居节点,在大循环体内,把这个邻居节点的名称赋给端口表里的目的地址,然后用一个小循环找到和这个邻居节点连接链路的端口号,在这个小循环里,也是遍历寻找的,遍历4条链路,得到其名称后,就可以截取出名称字符串中两段节点的名称,进行比较,然后得到发送方向的端口号,赋值到端口表内。
状态st_7中的代码:
上部:
op_intrpt_schedule_self(0.0,-1);
下部:
op_intrpt_schedule_self(op_sim_time()+0.0,0);
op_intrpt_schedule_self(op_sim_time()+0.0,1);
op_intrpt_schedule_self(op_sim_time()+0.0,2);
op_intrpt_schedule_self(op_sim_time()+0.0,3);
状态st_3中的代码:
Packet *pkptr;
pkptr=op_pk_create_fmt("packet3");
op_pk_send(pkptr,0);//从端口0发出
op_intrpt_schedule_self(op_sim_time()+1,0);//产生自中断0
状态st_4中的代码:
Packet *pkptr;
pkptr=op_pk_create_fmt("packet3");
op_pk_send(pkptr,1);
op_intrpt_schedule_self(op_sim_time()+1,1);
状态st_5中的代码:
Packet *pkptr;
pkptr=op_pk_create_fmt("packet3");
op_pk_send(pkptr,2);
op_intrpt_schedule_self(op_sim_time()+1,2);
状态st_6中的代码:
Packet *pkptr;
pkptr=op_pk_create_fmt("packet3");
op_pk_send(pkptr,3);
op_intrpt_schedule_self(op_sim_time()+1,3);
4.2接收节点
【HB】中代码:
#include
#define ARRIVAL (op_intrpt_type()==OPC_INTRPT_STRM&&op_intrpt_strm()==0)
状态st_2中的代码:
Packet *pkptr;
pkptr=op_pk_get(op_intrpt_strm());
op_pk_destroy(pkptr);
5.运行
端口表:
仿真动画: