Wikia

Enreas

Protocolos elementales de enlace de datos

Discusión0
236páginas en el wiki

Código tomado de la página de la cuarta edición del libro "Redes de computadoras", de Andrew S. Tanenbaum: http://authors.phptr.com/tanenbaumcn4/ En concreto, el enlace es: http://authors.phptr.com/tanenbaumcn4/programs/code.zip Por eso los comentarios del código están en inglés.

Declaraciones comunesEditar sección

#define MAX_PKT 1024	/* determines packet size in bytes */
 
typedef enum {false, true} boolean;	/* boolean type */
typedef unsigned int seq_nr;	/* sequence or ack numbers */
typedef struct {unsigned char data[MAX_PKT];} packet;	/*    packet definition */
typedef enum {data, ack, nak} frame_kind;	/* frame_kind definition */
 
typedef struct {	/* frames are transported in this layer */
  frame_kind kind;	/* what kind of a frame is it? */
  seq_nr seq;   	/* sequence number */
  seq_nr ack;   	/* acknowledgement number */
  packet info;  	/* the network layer packet */
} frame;
 
/* Wait for an event to happen; return its type in event. */
void wait_for_event(event_type *event);
 
/* Fetch a packet from the network layer for transmission on the channel. */
void from_network_layer(packet *p);
 
/* Deliver information from an inbound frame to the network layer. */
void to_network_layer(packet *p);
 
/* Go get an inbound frame from the physical layer and copy it to r. */
void from_physical_layer(frame *r);
 
/* Pass the frame to the physical layer for transmission. */
void to_physical_layer(frame *s);
 
/* Start the clock running and enable the timeout event. */
void start_timer(seq_nr k);
 
/* Stop the clock and disable the timeout event. */
void stop_timer(seq_nr k);
 
/* Start an auxiliary timer and enable the ack_timeout event. */
void start_ack_timer(void);
 
/* Stop the auxiliary timer and disable the ack_timeout event. */
void stop_ack_timer(void);
 
/* Allow the network layer to cause a network_layer_ready event. */
void enable_network_layer(void);
 
/* Forbid the network layer from causing a network_layer_ready event. */
void disable_network_layer(void);
 
/* Macro inc is expanded in-line: Increment k circularly. */
#define inc(k) if (k < MAX_SEQ) k = k + 1; else k = 0

Un protocolo símplex sin restriccionesEditar sección

/* Protocol 1 (utopia) provides for data transmission in one direction only, from
   sender to receiver.  The communication channel is assumed to be error free
   and the receiver is assumed to be able to process all the input infinitely quickly.
   Consequently, the sender just sits in a loop pumping data out onto the line as
   fast as it can. */
 
typedef enum {frame_arrival} event_type;
#include "protocol.h"
 
void sender1(void)
{
  frame s;			/* buffer for an outbound frame */
  packet buffer;		/* buffer for an outbound packet */
 
  while (true) {
        from_network_layer(&buffer);	/* go get something to send */
        s.info = buffer;	/* copy it into s for transmission */
        to_physical_layer(&s);	/* send it on its way */
  }	/* Tomorrow, and tomorrow, and tomorrow,
 	   Creeps in this petty pace from day to day
	   To the last syllable of recorded time.
	        - Macbeth, V, v */
}
 
 
void receiver1(void)
{
  frame r;
  event_type event;		/* filled in by wait, but not used here */
 
  while (true) {
        wait_for_event(&event);	 /* only possibility is frame_arrival */
        from_physical_layer(&r); /* go get the inbound frame */
        to_network_layer(&r.info); /* pass the data to the network layer */
  }
}

Protocolo símplex de parada y esperaEditar sección

/* Protocol 2 (stop-and-wait) also provides for a one-directional flow of data from
   sender to receiver. The communication channel is once again assumed to be error
   free, as in protocol 1. However, this time, the receiver has only a finite buffer
   capacity and a finite processing speed, so the protocol must explicitly prevent 
   the sender from flooding the receiver with data faster than it can be handled. */
 
typedef enum {frame_arrival} event_type;
#include "protocol.h"
 
void sender2(void)
{
  frame s;			/* buffer for an outbound frame */
  packet buffer;		/* buffer for an outbound packet */
  event_type event;		/* frame_arrival is the only possibility */
 
  while (true) {
        from_network_layer(&buffer); /* go get something to send */
        s.info = buffer;	/* copy it into s for transmission */
        to_physical_layer(&s);	/* bye-bye little frame */
        wait_for_event(&event);	/* do not proceed until given the go ahead */
  }
}
 
void receiver2(void)
{
  frame r, s;	/* buffers for frames */
  event_type event;		  /* frame_arrival is the only possibility */
  while (true) {
        wait_for_event(&event);	  /* only possibility is frame_arrival */
        from_physical_layer(&r);  /* go get the inbound frame */
        to_network_layer(&r.info);/* pass the data to the network layer */
        to_physical_layer(&s);	  /* send a dummy frame to awaken sender */
  }
}

Protocolo símplex para un canal con ruidoEditar sección

/* Protocol 3 (par) allows unidirectional data flow over an unreliable channel. */
#define MAX_SEQ 1		/* must be 1 for protocol 3 */
typedef enum  {frame_arrival, cksum_err, timeout} event_type;
#include "protocol.h"
void sender3(void)
{
  seq_nr next_frame_to_send;			/* seq number of next outgoing frame */
  frame s;					/* scratch variable */
  packet buffer;				/* buffer for an outbound packet */
  event_type event;
  next_frame_to_send = 0;			/* initialize outbound sequence numbers */
  from_network_layer(&buffer);			/* fetch first packet */
  while (true) {
        s.info = buffer;			/* construct a frame for transmission */
        s.seq = next_frame_to_send;		/* insert sequence number in frame */
        to_physical_layer(&s);			/* send it on its way */
        start_timer(s.seq);			/* if answer takes too long, time out */
        wait_for_event(&event);			/* frame_arrival, cksum_err, timeout */
        if (event == frame_arrival) {
                from_physical_layer(&s);	     /* get the acknowledgement */
                if (s.ack == next_frame_to_send) {
                        stop_timer(s.ack);	     /* turn the timer off */
                        from_network_layer(&buffer); /* get the next one to send */
                        inc(next_frame_to_send);     /* invert next_frame_to_send */
                }
        }
  }
}
 
void receiver3(void)
{
  seq_nr frame_expected;
  frame r, s;
  event_type event;
  frame_expected = 0;
  while (true) {
        wait_for_event(&event);			/* possibilities: frame_arrival, cksum_err */
        if (event == frame_arrival) {		/* a valid frame has arrived. */
                from_physical_layer(&r);	/* go get the newly arrived frame */
                if (r.seq == frame_expected) {	/* this is what we have been waiting for. */
                        to_network_layer(&r.info); /* pass the data to the network layer */
                        inc(frame_expected);	/* next time expect the other sequence nr */
                }
                s.ack = 1 - frame_expected;	/* tell which frame is being acked */
                to_physical_layer(&s);		/* send acknowledgement */
        }
  }
}

Spotlights de otras wikias
Solicita el tuyo aquí

Wiki aleatorio