⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 worker.c

📁 经典的数据链路层协议P1~P6的模拟器源代码和文档。最好在Linux下运行
💻 C
📖 第 1 页 / 共 2 页
字号:

void to_network_layer(packet *p)
{
/* Deliver information from an inbound frame to the network layer. A check is
 * made to see if the packet is in sequence.  If it is not, the simulation
 * is terminated with a "protocol error" message.
 */

  unsigned int num;

  num = pktnum(p);
  if (num != last_pkt_given + 1) {
	printf("Tick %u. Proc %d got protocol error.  Packet delivered out of order.\n", tick/DELTA, id); 
	printf("Expected payload %d but got payload %d\n",last_pkt_given+1,num);
	exit(0);
  }
  last_pkt_given = num;
  payloads_accepted++;
}

  
void from_physical_layer (frame *r)
{
/* Copy the newly-arrived frame to the user. */
 *r = last_frame;
}


void to_physical_layer(frame *s)
{
/* Pass the frame to the physical layer for writing on pipe 1 or 2. 
 * However, this is where bad packets are discarded: they never get written.
 */

  int fd, got, k;

  /* Fill in fields that that the simulator expects but some protocols do
   * not fill in or use.  This filling is not strictly needed, but makes the
   * simulation trace look better, showing unused fields as zeros.
   */
  switch(protocol) {
    case 2:
	s->seq = 0;

    case 3:
	s->kind = (id == 0 ? data : ack);
	if (s->kind == ack) {
		s->seq = 0;
		s->info.data[0] = 0;
		s->info.data[1] = 0;
		s->info.data[2] = 0;
		s->info.data[3] = 0;
	}
        break;

     case 4:
     case 5:
 	s->kind = data;
	break;

     case 6:
	if (s->kind == nak) {
		s->info.data[0] = 0;
		s->info.data[1] = 0;
		s->info.data[2] = 0;
		s->info.data[3] = 0;
	}

	/* The following statement is essential to protocol 6.  In that
	 * protocol, oldest_frame is automagically set properly to the
	 * sequence number of the frame that has timed out.  Keeping track of
	 * this information is a bit tricky, since the call to start_timer()
	 * does not tell what the sequence number is, just the buffer.  The
	 * simulator keeps track of sequence numbers using the array seqs[],
	 * which records the sequence number of each data frame sent, so on a
	 * timeout, knowing the buffer number makes it possible to determine
	 * the sequence number.
	 */
	if (s->kind==data) seqs[s->seq % (nseqs/2)] = s->seq; /* save seq # */
  }

  if (s->kind == data) data_sent++;
  if (s->kind == ack) acks_sent++;
  if (retransmitting) data_retransmitted++;

  /* Bad transmissions (checksum errors) are simulated here. */
  k = rand() & 01777;		/* 0 <= k <= about 1000 (really 1023) */
  if (k < pkt_loss) {	/* simulate packet loss */
	if (debug_flags & SENDS) {
		printf("Tick %u. Proc %d sent frame that got lost: ",
							    tick/DELTA, id);
		fr(s);
	}
	if (s->kind == data) data_lost++;	/* statistics gathering */
	if (s->kind == ack) acks_lost++;	/* ditto */
	return;

  }
  if (s->kind == data) data_not_lost++;		/* statistics gathering */
  if (s->kind == ack) acks_not_lost++;		/* ditto */
  fd = (id == 0 ? w1 : w2);

  got = write(fd, s, FRAME_SIZE);
  if (got != FRAME_SIZE) print_statistics();	/* must be done */

  if (debug_flags & SENDS) {
	printf("Tick %u. Proc %d sent frame: ", tick/DELTA, id);
	fr(s);
  }
}


void start_timer(seq_nr k)
{
/* Start a timer for a data frame. */

  ack_timer[k] = tick + timeout_interval + offset;
  offset++;
  recalc_timers();		/* figure out which timer is now lowest */
}


void stop_timer(seq_nr k)
{
/* Stop a data frame timer. */

  ack_timer[k] = 0;
  recalc_timers();		/* figure out which timer is now lowest */
}


void start_ack_timer(void)
{
/* Start the auxiliary timer for sending separate acks. The length of the
 * auxiliary timer is arbitrarily set to half the main timer.  This could
 * have been another simulation parameter, but that is unlikely to have
 * provided much extra insight.
 */

  aux_timer = tick + timeout_interval/AUX;
  offset++;
}


void stop_ack_timer(void)
{
/* Stop the ack timer. */

  aux_timer = 0;
}


void enable_network_layer(void)
{
/* Allow network_layer_ready events to occur. */

  network_layer_status = 1;
}


void disable_network_layer(void)
{
/* Prevent network_layer_ready events from occuring. */

  network_layer_status = 0;
}


int check_timers(void)
{
/* Check for possible timeout.  If found, reset the timer. */

  int i;

  /* See if a timeout event is even possible now. */
  if (lowest_timer == 0 || tick < lowest_timer) return(-1);

  /* A timeout event is possible.  Find the lowest timer. Note that it is
   * impossible for two frame timers to have the same value, so that when a
   * hit is found, it is the only possibility.  The use of the offset variable
   * guarantees that each successive timer set gets a higher value than the
   * previous one.
   */
  for (i = 0; i < NR_TIMERS; i++) {
	if (ack_timer[i] == lowest_timer) {
		ack_timer[i] = 0;	/* turn the timer off */
		recalc_timers();	/* find new lowest timer */
                oldest_frame = seqs[i];	/* for protocol 6 */
		return(i);
	}
  }
  printf("Impossible.  check_timers failed at %d\n", lowest_timer);
  exit(1);
}


int check_ack_timer()
{
/* See if the ack timer has expired. */

  if (aux_timer > 0 && tick >= aux_timer) {
	aux_timer = 0;
	return(1);
  } else {
	return(0);
  }
}


unsigned int pktnum(packet *p)
{
/* Extract packet number from packet. */

  unsigned int num, b0, b1, b2, b3;

  b0 = p->data[0] & BYTE;
  b1 = p->data[1] & BYTE;
  b2 = p->data[2] & BYTE;
  b3 = p->data[3] & BYTE;
  num = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
  return(num);
}


void fr(frame *f)
{
/* Print frame information for tracing. */

  printf("type=%s  seq=%d  ack=%d  payload=%d\n",
	tag[f->kind], f->seq, f->ack, pktnum(&f->info));
}

void recalc_timers(void)
{
/* Find the lowest timer */

  int i;
  bigint t = UINT_MAX;

  for (i = 0; i < NR_TIMERS; i++) {
	if (ack_timer[i] > 0 && ack_timer[i] < t) t = ack_timer[i];
  }
  lowest_timer = t;
}


void print_statistics(void)
{
/* Display statistics. */

  int word[3];

  sleep(1);
  printf("\nProcess %d:\n", id);
  printf("\tTotal data frames sent:  %9d\n", data_sent);
  printf("\tData frames lost:        %9d\n", data_lost);
  printf("\tData frames not lost:    %9d\n", data_not_lost);
  printf("\tFrames retransmitted:    %9d\n", data_retransmitted);
  printf("\tGood ack frames rec'd:   %9d\n", good_acks_recd);
  printf("\tBad ack frames rec'd:    %9d\n\n", cksum_acks_recd);

  printf("\tGood data frames rec'd:  %9d\n", good_data_recd);
  printf("\tBad data frames rec'd:   %9d\n", cksum_data_recd);
  printf("\tPayloads accepted:       %9d\n", payloads_accepted);
  printf("\tTotal ack frames sent:   %9d\n", acks_sent);
  printf("\tAck frames lost:         %9d\n", acks_lost);
  printf("\tAck frames not lost:     %9d\n", acks_not_lost);

  printf("\tTimeouts:                %9d\n", timeouts);
  printf("\tAck timeouts:            %9d\n", ack_timeouts);
  fflush(stdin);

  word[0] = 0;
  word[1] = payloads_accepted;
  word[2] = data_sent;
  write(mwfd, word, 3*sizeof(int));	/* tell main we are done printing */
  sleep(1);
  exit(0);
}


void sim_error(char *s)
{
/* A simulator error has occurred. */

  int fd;

  printf("%s\n", s);
  fd = (id == 0 ? w4 : w6);
  write(fd, &zero, TICK_SIZE);
  exit(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -