计算机网络原理实验七实验报告.doc_第1页
计算机网络原理实验七实验报告.doc_第2页
计算机网络原理实验七实验报告.doc_第3页
计算机网络原理实验七实验报告.doc_第4页
计算机网络原理实验七实验报告.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验七、传输层可靠传输协GBN编程实验报告序号: 姓名: 学号: 成绩 指导老师: 一、实验目的:1、通过编写实现一个简单可靠的数据传输协议GBN的发送和接收代码,模拟可靠数据传输2、理解TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。二、实验指导:参考教材。三、实验要求:编程实现一个GBN传输协议的发送方和接收方两程序,采用编程语言不限,要求能将发送接收流程以及处理方法表现出来.附源代码及注释通过本次实验,了解了GBN传输协议的相关知识,因为实验代码是由三部分组成,所以用Studio做实验时,要建立3个文件,一个是头文件,存放gbn.h, 另外2个是源文件,分别存放gbn.c 和 gbn-cs.c,然后再启动调试。实验代码通过查阅资料很容易理解,但是怎么实现这个程序对我来说是个问题。后来我把程序分了3部分,一个头文件和两个源文件,通过visual studio可以良好的运行,以下为老师附带代码的运行结果一、 GBN.h#pragma once#include /基础功能模块的数据结构声明#define BIDIRECTIONAL 1 /* change to 1 if youre doing extra credit and write a routine called B_output */* a msg is the data unit passed from layer 5 (teachers code) to layer 4 (students code). It contains the data (characters) to be delivered to layer 5 via the students transport level protocol entities. */struct msg char data20;/* a packet is the data unit passed from layer 4 (students code) to layer 3 (teachers code). Note the pre-defined packet structure, which all students must follow. */struct pktint seqnum;int acknum;int checksum;char payload20;#define WINDOWSIZE 8#define MAXBUFSIZE 50#define RTT 15.0#define NOTUSED 0#define NACK -1#define TRUE 1#define FALSE 0#define A 0#define B 1/网络仿真部分数据结构声明*struct eventfloat evtime; /* event time */int evtype; /* event type code */int eventity; /* entity where event occurs */struct pkt *pktptr; /* ptr to packet (if any) assoc w/ this event */struct event *prev;struct event *next; ;/* possible events: */#define TIMER_INTERRUPT 0 #define FROM_LAYER5 1#define FROM_LAYER3 2#define OFF 0#define ON 1/基础功能模块的函数声明*void ComputeChecksum(struct pkt *packet);/计算校验和int CheckCorrupted(struct pkt packet);/检查数据是否出错void A_output( struct msg message);/A端向外发送数据void A_input(struct pkt packet);/A端接收数据void A_timerinterrupt();/A计时器超时void A_init();/A端初始化void B_output(struct msg message); void B_input(struct pkt packet);void B_timerinterrupt();void B_init();/网络仿真部分的函数声明*void init(); /初始化仿真器float jimsrand();/随机数发生器0,1/处理事件列表部分的函数声明*void generate_next_arrival();/产生下一个到达的分组void insertevent(struct event *p);/向事件列表中插入一条新的事件void printevlist();/打印事件列表/*/*计时器模块*void stoptimer(int);/停止计时器void starttimer(int,float);/启动计时器/*/*网络各层之间传送模块*void tolayer3(int AorB,struct pkt packet);/向第3层发送信息void tolayer5(int AorB,char datasent20);/向第5层发送信息二、 GBN.c#include GBN.h#include #include #include extern int TRACE = 1; /* for my debugging */extern int nsim = 0; /* number of messages from 5 to 4 so far */ extern int nsimmax = 0; /* number of msgs to generate, then stop */extern float time = 0.000;float lossprob; /* probability that a packet is dropped */float corruptprob; /* probability that one bit is packet is flipped */float lambda; /* arrival rate of messages from layer 5 */ int ntolayer3; /* number sent into layer 3 */static int nlost = 0; /* number lost in media */static int ncorrupt = 0; /* number corrupted by media*/static int expectedseqnum = 0; /* expected sequence number at receiver side */static int nextseqnum; /* next sequence number to use in sender side */static int base; /* the head of sender window */struct pkt winbufWINDOWSIZE; /* window packets buffer */static int winfront,winrear; /* front and rear points of window buffer */static int pktnum;/* packet number of window buffer */struct msg bufferMAXBUFSIZE; /* sender message buffer */int buffront,bufrear; /* front and rear pointers of buffer */static int msgnum;/* message number of buffer */int packet_lost =0; int packet_corrupt=0;int packet_sent =0;extern int packet_correct=0;extern int packet_resent =0;int packet_timeout=0;extern struct event *evlist = NULL; /* the event list */计算校验和void ComputeChecksum( struct pkt *packet) int checksum;int i;checksum = packet-seqnum;checksum = checksum + packet-acknum;for ( i=0; ipayloadi);checksum = 0-checksum;packet-checksum = checksum;/检查是否出错int CheckCorrupted(struct pkt packet)int checksum;int i;checksum = packet.seqnum;checksum = checksum + packet.acknum;for ( i=0; i20; i+ ) checksum = checksum + (int)(packet.payloadi);if ( (packet.checksum+checksum) = 0 )return (FALSE);elsereturn (TRUE);/A端向外发送数据/* called from layer 5, passed the data to be sent to other side */void A_output(struct msg message)int i;struct pkt sendpkt;/* if window is not full */if ( nextseqnum base+WINDOWSIZE )printf(-A: New message arrives, send window is not full, send new messge to layer3!n);/* create packet */sendpkt.seqnum = nextseqnum;sendpkt.acknum = NOTUSED;for ( i=0; i20 ; i+ ) sendpkt.payloadi = message.datai;/* computer checksum */ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (A, sendpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* update state variables */ nextseqnum = nextseqnum+1; starttimer(A,RTT); B_input(sendpkt); A_input(sendpkt);/* if window is full */else printf(-A: New message arrives, send window is full,);/* if buffer full, give up and exit*/if ( msgnum = MAXBUFSIZE)printf ( Error: Sender buffer is full! n); exit (1); /* otherwise, buffer the message */ else printf(buffer new message!n); bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i20; i+) bufferbufrear.datai = message.datai; msgnum +; /B端向外发送数据/* called from layer 5, passed the data to be sent to other side */void B_output(struct msg message)int i;struct pkt sendpkt;/* if window is not full */if ( nextseqnum base+WINDOWSIZE )printf(-A: New message arrives, send window is not full, send new messge to layer3!n);/* create packet */sendpkt.seqnum = nextseqnum;sendpkt.acknum = NOTUSED;for ( i=0; i20 ; i+ ) sendpkt.payloadi = message.datai;/* computer checksum */ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (A, sendpkt);A_input(sendpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; pktnum +; winbufwinrear = sendpkt; for (i=0; i20; i+) winbufwinrear.payloadi= sendpkt.payloadi; /* if it is the first packet in window, start timeout */ /if ( base = nextseqnum ) / /starttimer(A,RTT); /printf(-A: start a new timer!n); / /* update state variables */ nextseqnum = nextseqnum+1;/* if window is full */else printf(-A: New message arrives, send window is full,);/* if buffer full, give up and exit*/if ( msgnum = MAXBUFSIZE)printf ( Error: Sender buffer is full! n); exit (1); /* otherwise, buffer the message */ else printf(buffer new message!n); bufrear = (bufrear+1) % MAXBUFSIZE; for (i=0; i20; i+) bufferbufrear.datai = message.datai; msgnum +; /A端接收数据void A_input(struct pkt packet)struct pkt sendpkt;int i;/* if received packet is not corrupted and ACK is received */ if ( (CheckCorrupted(packet) = FALSE) & (packet.acknum != NACK) )printf(-A: ACK %d is correctly received,packet.acknum);packet_correct+; /* delete the acked packets from window buffer */ winfront = (winfront+(packet.acknum+1-base) % WINDOWSIZE; pktnum = pktnum - (packet.acknum+1-base); /* move window base */ base = packet.acknum+1; stoptimer(A); if ( base nextseqnum) /starttimer(A,RTT); printf (nnnsend new packets!); /* if buffer is not empty, send new packets */ while ( (msgnum!=0) & (nextseqnumbase+WINDOWSIZE) )/* create packet */ sendpkt.seqnum = nextseqnum; sendpkt.acknum = NOTUSED; buffront = (buffront+1) % MAXBUFSIZE; for ( i=0; i20 ; i+ ) sendpkt.payloadi = bufferbuffront.datai; /* computer checksum */ ComputeChecksum (&sendpkt); /* if it is the first packet in window, start timeout */ if ( base = nextseqnum )/starttimer(A,RTT);printf (send new packets!n); /* send out packet */ tolayer3 (A, sendpkt); /* copy the packet to window packet buffer */ winrear = (winrear+1)%WINDOWSIZE; winbufwinrear = sendpkt; pktnum +; /* update state variables */nextseqnum = nextseqnum+1; /* delete message from buffer */msgnum -;else printf (-A: NACK is received, do nothing!n);/B端接收数据*一定要调用这个/* Note that with simplex transfer from a-to-B, there is no B_output() */* called from layer 3, when a packet arrives for layer 4 at B*/void B_input(struct pkt packet) struct pkt sendpkt;int i;/* if not corrupted and received packet is in order */if ( (CheckCorrupted(packet) = FALSE) & (packet.seqnum = expectedseqnum)printf(n-B: packet %d is correctly received, send ACK!n,packet.seqnum);/* send an ACK for the received packet */ /* create packet */ sendpkt.seqnum = NOTUSED; sendpkt.acknum = expectedseqnum; for ( i=0; i20 ; i+ )sendpkt.payloadi = 0; /* computer checksum */ ComputeChecksum (&sendpkt); /* send out packet */tolayer3 (B, sendpkt);/* update state variables */expectedseqnum = expectedseqnum+1; printf(-B:expectedseqnum = %dn,expectedseqnum); /* deliver received packet to layer 5 */ /tolayer5(B,packet.payload); /* otherwise, discard the packet and send a NACK */ elseprintf(-B: packet %d is corrupted or not I expects, send NACK!n,packet.seqnum); /* create packet */ sendpkt.seqnum = NOTUSED; sendpkt.acknum = NACK; for ( i=0; i20 ; i+ ) sendpkt.payloadi = 0; /* computer checksum */ ComputeChecksum (&sendpkt); /* send out packet */ tolayer3 (B, sendpkt); /A计时器超时/* called when As timer goes off */void A_timerinterrupt()int i;printf(-A: time out,resend packets!n);/* start timer */starttimer(A,RTT);/* resend all packets not acked */for ( i=1; i=pktnum; i+ )packet_resent+; tolayer3(A,winbuf(winfront+i)%WINDOWSIZE); /B计时器超时/* called when Bs timer goes off */void B_timerinterrupt()int i;printf(-B: time out,resend packets!n);/* start timer */starttimer(B,RTT);/* resend all packets not acked */for ( i=1; i 0.0: ); /fscanf(fp,%f,&lambda);scanf(%f,&lambda); printf(nEnter TRACE: );/fscanf(fp,%d,&TRACE);scanf(%d,&TRACE);printf(nn);srand(9999); /* init random number generator */sum = 0.0; /* test random number generator for students */for (i=0; i1000; i+)sum=sum+jimsrand(); /* jimsrand() should be uniform in 0,1 */avg = sum/1000.0; /*if(avg 0.75) printf(It is likely that random number generation on your machinen ); printf(is different from what this emulator expects. Please taken); printf(a look at the routine jimsrand() in the emulator code. Sorry. n); exit(0); */ printf(%f,avg);ntolayer3 = 0;nlost = 0;ncorrupt = 0;time=0.0; /* initialize time to 0.0 */ generate_next_arrival(); /* initialize event list */随机数发生器float jimsrand() double mmm = 2147483647; /* largest int - MACHINE DEPENDENT! */float x; /* individual students may need to change mmm */ x = rand()/mmm; /* x should be uniform in 0,1 */return(x); /*/*事件处理部分*void generate_next_arrival()double x,log(),ceil();struct event *evptr;float ttime;int tempint;/if (TRACE2)/printf(-GENERATE NEXT ARRIVAL: creating new arrivaln);x = lambda*jimsrand()*2; /* x is uniform on 0,2*lambda */ /* having mean of lambda */evptr = (struct event *)malloc(sizeof(struct event);evptr-evtime = time + x; evptr-evtype = FROM_LAYER5;if (jimsrand()eventity = A;elseevptr-eventity = B;insertevent(evptr);/向事件列表中插入一条新的事件void insertevent(struct event *p) struct event *q,*qold;if (TRACE2)/printf( INSERTEVENT: time is %lfn,time);/printf( INSERTEVENT: future time will be %lfn,p-evtime); q = evlist; /* q points to front of list in which p struct inserted */if (q=NULL)/* list is empty */ evlist=p; p-next=NULL; p-prev=NULL; else 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)/* front 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;/打印事件列表void printevlist()struct event *q;int i;printf(-nEvent List Follows:n);for(q = evlist; q!=NULL; q=q-next)printf(Event time: %f, type: %d entity: %dn,q-evtime,q-evtype,q-eventity); printf(-n);/启动计时器void starttimer(int AorB,float increment)struct event *q;struct event *evptr;if (TRACE2)printf(n-A: START TIMER: starting timer at %fn,time);/* be nice: check to see if timer is already started, if so, then warn */* for (q=evlist; q!=NULL & q-next!=NULL; q = q-next) */for (q=evlist; q!=NULL ; q = q-next)if ( (q-evtype=TIMER_INTERRUPT & q-eventity=AorB) ) /printf(Warning: attempt to start a timer that is already startedn);return;/* create future event for when timer goes off */evptr = (struct event *)malloc(sizeof(struct event);evptr-evtime = time + increment;evptr-evtype = TIMER_INTERRUPT;evptr-eventity = AorB;insertevent(evptr); /停止计时器/* called by students routine to cancel a previously-started timer */void stoptimer(int AorB) /* A or B is trying to stop timer */struct event *q,*qold;if (T

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论