毕业论文论文范文课程设计实践报告法律论文英语论文教学论文医学论文农学论文艺术论文行政论文管理论文计算机安全
您现在的位置: 毕业论文 >> 论文 >> 正文

Dynamips设计与分析-Dynamips及相关教学软件研究与设计 第16页

更新时间:2009-4-16:  来源:毕业论文
Dynamips设计与分析-Dynamips及相关教学软件研究与设计 第16页
第四章 各层实现方法
通过第三章,了解了各层需要仿真的通信层协议,本章将具体分析各层是如何实现的。

4.1 物理层的实现
在本节简单分析下用UDP报文模拟传输的实现。
在Dynamips中使用了一个udp_connect函数来实现创建一个新的socket连接到指定的主机,其中的getaddrinfo函数返回的结构体struct addrinfo类型的成员包含了一个ai_addr的成员,该成员的类型是struct sockaddr,同时,addrinfo中还包含了ai_family, ai_socktype, ai_protocol成员,因此可以直接通过该返回结构来进行socket等函数的套接口调用。
通过getaddrinfo函数得到该主机对应服务的所有的IP,然后尝试与其中一个IP来建立套接口进行连接。
具体函数实现如下:
/* 创建一个新的socket连接到指定的主机 */
/* local_port即本地端口,remote_host即远程主机,remote_port即远程端口 */
int udp_connect(int local_port,char *remote_host,int remote_port)
{
   struct addrinfo hints,*res,*res0;
   struct sockaddr_storage st;
   int error, sck = -1;
   char port_str[20]; /* 定义了port_str数组及大小 */
   memset(&hints,0,sizeof(hints));    /* 初始化内存空间 */
   hints.ai_family = PF_UNSPEC;   /* IPv4,IPv6都支持,将返回这2中类型的地址 */
   hints.ai_socktype = SOCK_DGRAM;
   snprintf(port_str,sizeof(port_str),"%d",remote_port);  
 /* 将参数远程端口remote_port按照整数的格式格式化,然后将其复制到port_str中,如果格式化后的长度<sizeof(port_str),则将此字符串全部复制到port_str中,并给其后添加一个字符串结束符('\0'),如果格式化后的长度=>sizeof(port_str),则只将其中的(sizeof(port_str)-1)个字符复制到port_str中,并给其后添加一个字符串结束符('\0')。*/
   if ((error = getaddrinfo(remote_host,port_str,&hints,&res0)) != 0) {
      fprintf(stderr,"%s\n",gai_strerror(error));
      return(-1);
   }
    /* 遍历 */
   for(res=res0;res;res=res->ai_next)
   {
      /* 仅要IPv4和IPv6 */
      if ((res->ai_family != PF_INET) && (res->ai_family != PF_INET6))
         continue;
      /* 创建新的socket */
      if ((sck = socket(res->ai_family,SOCK_DGRAM,res->ai_protocol)) < 0) {
         perror("udp_connect: socket");
         continue;
      }
      /* 绑定到本地端口 */
      memset(&st,0,sizeof(st));    /* 初始化内存空间 */
       /* 以下语句判断IPv4,IPv6,或其它情况 */
      switch(res->ai_family) {
         case PF_INET: {
            struct sockaddr_in *sin = (struct sockaddr_in *)&st;
            sin->sin_family = PF_INET;
            sin->sin_port = htons(local_port);
            break;
         } /* IPv4 */
         case PF_INET6: {
            struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&st;
#ifdef SIN6_LEN
            sin6->sin6_len = res->ai_addrlen;
#endif
            sin6->sin6_family = PF_INET6;
            sin6->sin6_port = htons(local_port);
            break;
         }  /* IPv6 */
         default:
            /* 不应该发生 */
            close(sck);
            sck = -1;
            continue;
      }
      /* 尝试连接到远程主机 */
      if (!bind(sck,(struct sockaddr *)&st,res->ai_addrlen) &&
          !connect(sck,res->ai_addr,res->ai_addrlen))
         break;
      close(sck);
      sck = -1;
   }
   freeaddrinfo(res0); /* 此处调用来释放getaddrinfo函数动态分配的内存 */
   return(sck);
}

4.2 数据链路层的实现
在本层主要实现两个:虚拟帧中继交换机,虚拟以太网交换机。
4.2.1 虚拟帧中继交换机的实现
在这里主要分析如下几个部分:
 创建一个帧中继交换机
 删除一个帧中继交换机
 创建一个交换机连接
 删除一个交换机连接
 保存帧中继的配置信息
 读取帧中继交换机配置文件
 启动一个帧中继交换机
1.创建一个虚拟交换机表
要想创建一个虚拟交换机表,首先要为要创建的这个表分配空间,初始化内存,初始化互斥锁对象,然后在固定的内存里面创建一个池,这里命名为Frame-Relay Switch,内存大小是t->mp占用空间的大小,然后进行命名,并且在注册表中增加一个记录,这样就创建了一个虚拟交换要表。
此函数实现如下:
frsw_table_t *frsw_create_table(char *name)
{
   frsw_table_t *t;
   if (!(t = malloc(sizeof(*t))))
      return NULL;
   memset(t,0,sizeof(*t)); /* 初始化内存 */
   pthread_mutex_init(&t->lock,NULL); /* 初始化一个互斥锁对象 */
mp_strdup(&t->mp,name)))
      goto err_name;
   if (registry_add(t->name,OBJ_TYPE_FRSW,t) == -1) {
      fprintf(stderr,"frsw_create_table: unable to create switch '%s'\n",name);
      goto err_reg;
   }
   return t;
 err_reg:        /* 出错处理 */
 err_name:
   mp_free_pool(&t->mp);
   free(t);
   return NULL;
}

 << 上一页  [11] [12] [13] [14] [15] [16] [17] [18] [19] [20]  ... 下一页  >> 

Dynamips设计与分析-Dynamips及相关教学软件研究与设计 第16页下载如图片无法显示或论文不完整,请联系qq752018766
设为首页 | 联系站长 | 友情链接 | 网站地图 |

copyright©751com.cn 辣文论文网 严禁转载
如果本毕业论文网损害了您的利益或者侵犯了您的权利,请及时联系,我们一定会及时改正。