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

📄 worker.c

📁 四个网络协议在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 + -