DV算法2

作者:冰蓝沸点 

2007年05月21日 星期一 16:50

DVSim.cpp:
/*****************************************************************
*    DVsim.c     Distance Vector Routing Simulation Package
*
*    Event driven simulation of distributed, asynchronous,
*    distance vector routing. This file contains the network
*    simulation code which emulates layer 2 and below:
*
*         - simulates packet tranmissions between two
*        physically connected nodes
*
*        - assumes with no packet loss or corruption
*
*         - calls initializations routines rtinit0, etc., before
*            beginning simulation
*
*
*    Original code from Kurose and Ross, Computer Networking
*
*    Modified by S. Dykes     Apr. 2000
*    1. Changed RNG to use drand48() with seed = getpid()
*    2. Replaced 999 with INF
*    3. created common include file DVsim.h
*    4. extended to 6 node network
*
*---------------------------------------------------------------*/
#define        DVSIM_H
#include     "DVsim.h"

#define     FROM_LAYER2     2
#define     LINK_CHANGE     10

extern int rpc0;
extern int rpc1;
extern int rpc2;
extern int rpc3;
extern int rpc4;
extern int spc0;
extern int spc1;
extern int spc2;
extern int spc3;
extern int spc4;

/*----------------------------------------
*     Event list and possible events
*---------------------------------------*/
struct event
{
   double    evtime;         /* event time */
   int         evtype;         /* event type code */
   int         eventity;       /* entity where event occurs */
   struct rtpkt *rtpktptr;     /* ptr to packet (if any) assoc w/ this event */
   struct event *prev;
   struct event *next;
};
struct event *evlist = NULL;  

/*--------------------------------
*     Simulation clock
*-------------------------------*/
double    clocktime = 0.000;
double    get_clock() { return clocktime; }

/*--------------------------------
*     Function prototypes
*-------------------------------*/
void     init();
void     insertevent (struct event *);
void     printevlist();
void     tolayer2 (struct rtpkt );

/*-------------------------------
*    MAIN
*-------------------------------*/
int main()
{
   struct event *eventptr;
   int i;
  
   /*----------------------------------------
   *     Loop until we run out of events
   *---------------------------------------*/
   init();
   printdt_0(&dt[0]);
   printdt_1(&dt[1]);
   printdt_2(&dt[2]);
   printdt_3(&dt[3]);
   printdt_4(&dt[4]);
   while (1)
   {
    /*----------------------------------------
    *    Get next event from top of list
    *       Done if event list is empty
    *---------------------------------------*/
        if (! (eventptr = evlist) ) break;           
        evlist = evlist->next;       
        if (evlist) evlist->prev=NULL;

    /*----------------------------------------
    *    Trace info
    *---------------------------------------*/
        if (TRACE>1) {
           printf("/nMAIN: rcv event, t=%.3f, at %d",    
            eventptr->evtime, eventptr->eventity);
           if (eventptr->evtype == FROM_LAYER2 ) {
          printf(" src:%2d,", eventptr->rtpktptr->sourceid);
              printf(" dest:%2d,", eventptr->rtpktptr->destid);
              printf(" contents: ");
          for (i=0; i<NODES; i++) printf ("%3d ",eventptr->rtpktptr->mincost[i]);
              printf("/n");
       }
        }
    /*----------------------------------------
    *    Update clock to next event time
    *---------------------------------------*/
        clocktime = eventptr->evtime;   

    /*----------------------------------------
    *    Call event handler
    *---------------------------------------*/
        if (eventptr->evtype == FROM_LAYER2 ) {
            if      (eventptr->eventity == 0) {rtupdate0(eventptr->rtpktptr);printdt_0(&dt[0]);}
            else if (eventptr->eventity == 1) {rtupdate1(eventptr->rtpktptr);printdt_1(&dt[1]);}
            else if (eventptr->eventity == 2) {rtupdate2(eventptr->rtpktptr);printdt_2(&dt[2]);}
            else if (eventptr->eventity == 3) {rtupdate3(eventptr->rtpktptr);printdt_3(&dt[3]);}
            else if (eventptr->eventity == 4) {rtupdate4(eventptr->rtpktptr);printdt_4(&dt[4]);}
            else { printf("Panic: unknown event entity/n"); exit(0); }
    }
        else if (eventptr->evtype == LINK_CHANGE ) {
            if (clocktime < 10001.0) { linkhandler0(1,20); linkhandler1(0,20); }
        else                { linkhandler0(1,1); linkhandler1(0,1); }
    }
        else {  
        printf("Panic: unknown event type/n");
        exit(0);
        }
    /*--------------------------------------------------------
    *    Free memory for packet (if any) and event struct
    *-------------------------------------------------------*/
        if (eventptr->evtype == FROM_LAYER2 ) free(eventptr->rtpktptr);     
        free(eventptr);                
   }
   /*-------------------------------
   *    SIMULATION TERMINATED
   *-------------------------------*/
   printf("/nSimulator terminated at t=%f, no packets in medium/n", clocktime);
   cout << "Node0 total sended " << spc0 << " packets and received " << rpc0 << " packets." << endl;
   cout << "Node1 total sended " << spc1 << " packets and received " << rpc1 << " packets." << endl;
   cout << "Node2 total sended " << spc2 << " packets and received " << rpc2 << " packets." << endl;
   cout << "Node3 total sended " << spc3 << " packets and received " << rpc3 << " packets." << endl;
   cout << "Node4 total sended " << spc4 << " packets and received " << rpc4 << " packets." << endl;
   return 0;
}


/*-------------------------------
*    init
*-------------------------------*/
void     init()    
{
   int i;
   double    sum, avg;
   struct event *evptr;

   /*---------------------
   *     Input TRACE
   *--------------------*/
   printf ("Enter value for TRACE (no trace =0, user= 1 or 2, developer= 3): ");
   scanf ("%d", &TRACE);

   /*---------------------
   *     Test RNG
   *--------------------*/
   srand ((unsigned) getpid());
   for (i = 0, sum = 0.; i < 1000; i++) sum += rand();
   avg = (sum / 1000.0 - 15000) / 2000;
   if (avg < 0.25 || avg > 0.75) {
       printf("RNG PROBLEM/n");
    printf("Average of 1000 random numbers is %g   (expected 0.5)./n", avg);
       printf("It is likely that random number generation on your machine/n");
       printf("is different from what this emulator expects. Please take/n");
       printf("a look at the routine init() in the emulator code. /n");
       exit(0);
   }
   /*-------------------------------------
   *     Initialize clock and nodes
   *------------------------------------*/
   clocktime = 0.0;
   rtinit0();
   rtinit1();
   rtinit2();
   rtinit3();
   rtinit4();

   /*-------------------------------------
   *     Initialize future link changes   
   *------------------------------------*/
   if (LINKCHANGES == 1)  
   {
       evptr = (struct event *)malloc(sizeof(struct event));
       evptr->evtime = 10000.0;
       evptr->evtype = LINK_CHANGE;
       evptr->eventity = -1;
       evptr->rtpktptr = NULL;
       insertevent(evptr);
       evptr = (struct event *)malloc(sizeof(struct event));
       evptr->evtype = LINK_CHANGE;
       evptr->evtime = 20000.0;
       evptr->rtpktptr = NULL;
       insertevent(evptr);   
   }
}

/********************* EVENT HANDLING ROUTINES *******
*
*     These routines handle the event list
*
*****************************************************/
/*------------------------------------------------------------
*    insertevent
*
*        Inserts object in event list. List is sorted by time.
*    p -> object to be inserted
*     q -> top of list
*------------------------------------------------------------*/
void     insertevent (struct event *p)
{
   struct event *q,*qold;

   if (TRACE>3) {
      printf("            INSERTEVENT: time is %lf/n",clocktime);
      printf("            INSERTEVENT: future time will be %lf/n",p->evtime);
   }
   q = evlist;        
   if (q==NULL) {           
     /*--------------------------------
           *   Empty list - insert at top
     *-------------------------------*/
        evlist=p;
        p->next=NULL;
        p->prev=NULL;
   }
   else {
     /*----------------------------------------
           *   Find event time > p's time
     *---------------------------------------*/
        for (qold=q; q !=NULL && p->evtime > q->evtime; q=q->next) qold=q;

        if (q==NULL) {      
        /*---------------------
              *   End of list
        *--------------------*/
           qold->next = p;
           p->prev = qold;
           p->next = NULL;
        }
        else if (q==evlist) {        
        /*---------------------
              *   Top of list
        *---------------------*/
           p->next=evlist;
           p->prev=NULL;
           p->next->prev=p;
           evlist = p;
        }
        else {                
        /*---------------------
              *   Middle of list
        *---------------------*/
           p->next=q;
           p->prev=q->prev;
           q->prev->next=p;
           q->prev=p;
        }
    }
}


/*------------------------------------------------------------
*    printevlist - prints event list
*------------------------------------------------------------*/
void     printevlist()
{
   struct event *q;
   printf("--------------/nEvent List Follows:/n");
   for (q = evlist; q!=NULL; q=q->next)
      printf("Event time: %f, type: %d entity: %d/n",q->evtime,q->evtype,q->eventity);
   printf("--------------/n");
}


/*------------------------------------------------------------
*    tolayer2
*------------------------------------------------------------*/
void     tolayer2 (struct rtpkt packet)
{
   struct rtpkt *mypktptr;
   struct event *evptr, *q;
   double    lastime;
   int         i;

/*-------------------------------------------------------------------------
* Check for packet errors
* Check if source and destination id's are reasonable
*-------------------------------------------------------------------------*/
   if (packet.sourceid<0 || packet.sourceid >NODES) {
      printf("WARNING: illegal source id in your packet, ignoring packet!/n");
      return;
   }
   if (packet.destid<0 || packet.destid >NODES) {
      printf("WARNING: illegal dest id in your packet, ignoring packet!/n");
      return;
   }
   if (packet.sourceid == packet.destid) {
      printf("WARNING: source and destination id's the same, ignoring packet!/n");
      return;
   }
   if (linkcost[packet.sourceid][packet.destid] == INF) {
      printf("WARNING: source and destination not connected, ignoring packet!/n");
      return;
   }

/*-------------------------------------------------------------------------
* Make a copy of the packet student just gave me since he/she may decide
* to do something with the packet after we return back to him/her.
*-------------------------------------------------------------------------*/
mypktptr = (struct rtpkt *) malloc(sizeof(struct rtpkt));
mypktptr->sourceid = packet.sourceid;
mypktptr->destid   = packet.destid;
for (i=0; i<NODES; i++) mypktptr->mincost[i] = packet.mincost[i];

/*---------------------
* Print trace info
*--------------------*/
if (TRACE>2)
{
     printf("    TOLAYER2: source: %d, dest: %d/n              costs:",
              mypktptr->sourceid, mypktptr->destid);
     for (i=0; i<4; i++)   printf("%d ",mypktptr->mincost[i]);
     printf("/n");
}

/*-----------------------------------------------------------------
* Create future event for arrival of packet at the other side
*-----------------------------------------------------------------*/
evptr           = (struct event *)malloc(sizeof(struct event));
evptr->evtype   = FROM_LAYER2;     /* packet will pop out from layer3 */
evptr->eventity = packet.destid;     /* event occurs at other entity */
evptr->rtpktptr = mypktptr;           /* save ptr to my copy of packet */

/*-----------------------------------------------------------------
* Compute the arrival time of packet at the other end.
* Medium can not reorder, so make sure packet arrives between 1 and 10
*     time units after the latest arrival time of packets
*     currently in the medium on their way to the destination
*-----------------------------------------------------------------*/
lastime = clocktime;
for (q=evlist; q!=NULL ; q = q->next)
{
     if ( (q->evtype==FROM_LAYER2 && q->eventity==evptr->eventity) )
         lastime = q->evtime;
}
evptr->evtime = lastime + 2. * rand();

/*------------------
* Trace info
*-----------------*/
if (TRACE>2) printf("    TOLAYER2: scheduling arrival on other side/n");

/*---------------------------------------------------
* Insert message arrival into event list
*--------------------------------------------------*/
insertevent(evptr);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值