计算机网络原理实验七实验报告文档下载_第1页
计算机网络原理实验七实验报告文档下载_第2页
计算机网络原理实验七实验报告文档下载_第3页
计算机网络原理实验七实验报告文档下载_第4页
计算机网络原理实验七实验报告文档下载_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

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

文档简介

实验七、 传输层可靠传输协议 GBN 编程实验报告 一、实验目的: 1、编程实现简单可靠的数据传输 GBN协议,模拟可靠数据传输 2、理解 TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。 二、实验指导: 参考教材。 三、实验要求: 编程实现一个 GBN传输协议,采用编程语言不限,要求能将发送接收流程以及处理方法表现出来 .附源代码及注释并附上实验结果截图。 一、 GBN.h #pragma once #include /基础功能模块的数据结构声明 #define BIDIRECTIONAL 1 /* change to 1 if youre doing extra credit and write a routine called B_output */ 如果你想做酷文解码和写一个程序叫B_output 就改变值为 1 /* 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. */ 一个“ msg”是从第五层传送到第四层的数据单元 .它包含通过传送层协议被传送到第五层的数据 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 pkt int 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 event float 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 */ 目前为止信息的数字是从 5到 4 extern int nsimmax = 0; /* number of msgs to generate, then stop */ 如果信息产生的数字为 0,然后就停止 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); else return (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*/ 来自第三层,当这个数据包在 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 */否则,丢弃这个数据包和发送否定应答 else printf(-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 */ 当 A时器进行时 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 */ 当 B时器进行时 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 */ 个别学生可能需要改变 mmm x = rand()/mmm; /* x should be uniform in 0,1 */ return(x); /* /* 事件处理部分* void generate_next_arrival() double x,log(),ceil(); struct event *evptr; char *malloc(); 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; else evptr-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 */q指着 p结构要插入的列表前面的地方 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; char *malloc(); 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 (TRACE2) printf(n-A: STOP TIMER: stopping timern); /* 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) )/* remove this event */ if (q-next=NULL & q-prev=NULL) evlist=NULL; /* remove first and only event on list */ 删除第一个和只有一个事件在列表 else if (q-next=NULL) /* end of list - there is one in front */ q-prev-next = NULL; else if (q=evlist) /* front of list - there must be event after */ 列表有开始就一定会有结束 q-next-prev=NULL; evlist = q-next; else /* middle of list */ 列表的中间 q-next-prev = q-prev; q-prev-next = q-next; free(q); return; /printf(Warning: unable to cancel your timer. It wasnt running.n); /向第三层发送信息 /* TOLAYER3 */ void tolayer3(int AorB,struct pkt packet) struct pkt *mypktptr; struct event *evptr,*q; char *malloc(); float lastime, x, jimsrand(); int i; ntolayer3+; /* simulate losses: */ 模拟丢失 if (jimsrand() 0) printf( TOLAYER3: packet being lostn); 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 pkt *)malloc(sizeof(struct pkt); mypktptr-seqnum = packet.seqnum; mypktptr-acknum = packet.acknum; mypktptr-checksum = packet.checksum; for (i=0; ipayloadi = packet.payloadi; if (TRACE2) printf( TOLAYER3: seq: %d, ack %d, check: %d , mypktptr-seqnum,mypktptr-acknum, mypktptr-checksum); for (i=0; ipayloadi); printf(); /* create future event for arrival of packet at the other side */ 创建远景即使数据包到达另一边 evptr = (struct event *)malloc(sizeof(struct event); evptr-evtype = FROM_LAYER3; /* packet will pop out from layer3 */ 数据包将会从第三层弹出 evptr-eventity = (AorB) % 2; /* event occurs at other entity */ 事件发生在其他实体 evptr-pktptr = mypktptr; /* save ptr to my copy of packet */ 保存指针,该指针指的是我复制的数据包 lastime = time; /* for (q=evlist; q!=NULL & q-next!=NULL; q = q-next) */ for (q=evlist; q!=NULL ; q = q-next) if ( (q-evtype=FROM_LAYER3 & q-eventity=evptr-eventity) ) lastime = q-evtime; evptr-evtime = lastime + 1 + 9*jimsrand(); /* simulate corruption: */ 模拟损坏 if (jimsrand() corruptprob) ncorrupt+; if ( (x = jimsrand() payload0=Z; /* corrupt payload */ 损坏的有效负载 else if (x seqnum = 999999; else mypktptr-acknum = 999999; if (TRACE0) printf( TOLAYER3: packet being corruptedn); /if (TRACE2) /printf( TOLAYER3: scheduling arrival on other siden); insertevent(evptr); /向第五层发送信息 /* TOLAYER5 */ void tolayer5(int AorB,char datasent20) int i; if (TRACE2) printf( TOLAYER5: data received: ); for (i=0; i20; i+) printf(%c,datasenti); printf(n); 三、 GBN-CS.c #include #include GBN.h extern int TRACE ; /* for my debugging */ 我的调试 extern int nsim ; /* number of messages from 5 to 4 so far */ 至今为止从从第五到第四的数据信息 extern int nsimmax; /* number of msgs to generate, then stop */ 将产生大量的信息,然后结束 extern float time; extern int packet_correct; extern int packet_resent; extern struct event *evlist; int main() struct event *eventptr; struct msg msg2give; struct pkt pkt2give; int i,j; char c; init(); A_init(); B_init(); while (1) eve

温馨提示

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

评论

0/150

提交评论