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

下载本文档

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

文档简介

1、实验七、传输层可靠传输协议GBN编程实验报告一、实验目的:1、编程实现简单可靠的数据传输GBN协议,模拟可靠数据传输2、理解TCP协议可靠传输的差错检测、重传、累计确认、定时器的可靠传输策略。二、实验指导:参考教材。三、实验要求:编程实现一个GBN传输协议,采用编程语言不限,要求能将发送一一接收流程以及处理方法 表现出来.附源代码及注释并附上实验结果截图。一、GBN.h#pragma once#include 基础功能模块的数据结构声明#define BIDIRECTIONAL 1/* change to 1 if youre doing extra credit andwrite a rou

2、tine 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”是从第五层传送到第四层的数据单元.它包含通过传送层协议被传送到 第五层的

3、数据 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;#de

4、fine WINDOWSIZE 8#define MAXBUFSIZE 50#define RTT 15.0#define NOTUSED 0#define NACK -1 TOC o 1-5 h z #define TRUE1#define FALSE0#define A0#define B1网 络 仿 真 部 分 数 据 结 构声明 * struct event float evtime;/* event time */ 事件时间int evtype;/* event type code */ 事件类型代码int eventity;/* entity where event occurs

5、*/ 所在的实体事件发生时struct pkt *pktptr; /* ptr to packet (if any) assoc w/ this event */ 用指针来显示这个数据包 struct event *prev;struct event *next;/* possible events: */可能发生#define TIMER_INTERRUPT 0 TOC o 1-5 h z #defineFROM_LAYER51#defineFROM_LAYER32#defineOFF0#defineON1 基 础 功 能 模 块 的 函 数 声 明 * void ComputeChecks

6、um(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_timerin

7、terrupt();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);/ 启动计时器 /*

8、/* 网络各层之间传送模块 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到4extern

9、 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

10、 5 */ 从第五层到达的信息的次序int ntolayer3;/* number sent into layer 3 */被传送到第三层的数据/* number lost in media */ 在媒介中/* number lost in media */ 在媒介中心r LE AU数据丢失static int ncorrupt = 0;/* number corrupted by media*/被媒介毁坏的数据static int expectedseqnum = 0;/* expected sequence number atreceiver side */在接收者这边接收到预期的序列数据

11、static int nextseqnum;/* next sequence number to use insender 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

12、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 =

13、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-

14、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

15、端向外发送数据/* 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 newmessge to layer3!n)

16、;/* 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 */ 复制数据包到窗口 数据缓冲区

17、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 */ 如果窗口没有满elseprintf(A: New message arri

18、ves, 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 */ 否则,缓冲信息elseprintf(buffer new message!n);bufrear = (bufrear+1) % MAXBUFSIZE;for (i=0; i20; i+)bufferbufrear.dat

19、ai = 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 fu

20、ll, send newmessge 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

21、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

22、: start a new timer!n);/ /* update state variables */ 更新状态变量 nextseqnum = nextseqnum+1;/* if window is full */ 如果窗口已经满了elseprintf(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 (

23、1);/* otherwise, buffer the message */ 否则,缓冲信息elseprintf(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 *

24、/如果接收到的数据包没有被损坏和确认已经被接收了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 - (pa

25、cket.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.se

26、qnum = 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 )/star

27、ttimer(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

28、 buffer */ 删除缓冲区的信息 msgnum -;elseprintf (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;i

29、nt i;/* if not corrupted and received packet is in order */如果没有损坏和接收到的数据包是井然有序的if ( (CheckCorrupted(packet) = FALSE) & (packet.seqnum = expectedseqnum) printf(nB: packet %d is correctly received, sendACK!n”,packet.seqnum);/* send an ACK for the received packet */发送这个接收到的数据包的 确认/* create packet */ 创建

30、数据包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:expectedseqnu

31、m = %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, sendNACK!n”,packet.seqnum);/* create packet */ 创建数据包 sendpkt.seqnum = N

32、OTUSED;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);/

33、* 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 ti

34、mer */ 开始计时器 starttimer(B,RTT);/* resend all packets not acked */重发没有被确认的所有数据包for ( i=1; i0.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 g

35、enerator 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

36、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!*/最大的中断-与机器相关的flo

37、at x;/* individual students may need to change mmm*/个别学生可能需要改变minmx = 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 ARRIVA

38、L: creating newarrivaln);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);向事件列表中插入一条新的

39、事件void insertevent(struct event *p)struct event *q,*qold;if (TRACE2)/printf(INSERTEVENT: time is %lfn”,time);/printf(INSERTEVENT: future time willbe %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-ne

40、xt=NULL;p-prev=NULL;elsefor (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

41、-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(Eventtime:%f,type:%dentity: %dn”,q-evtime,q-evtype,q-eventity);printf(n);启动计时器void starttimer(int AorB,float increment)struct event *q;struct event *evpt

42、r;char *malloc();if (TRACE2)printf(nA: 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_INTER

43、RUPT & 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; in

44、sertevent(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(nA: STOP TIMER: stopping timern);/* for (q=evlist; q!=NULL & q-next!=NULL; q = q-next) */for (q=evlist; q!

45、=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

46、 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);向第三层发送信息/4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*

47、 TAT A VT7DQ 4*4*4*4*4*4*4*4*4*4*4*4*4*4*4* / /* TULAYER3 */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;/* mak

48、e 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;mypktpt

49、r-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

50、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!=

51、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; /* corru

52、pt payload */损坏的有效负载else if (x seqnum = 999999;elsemypktptr-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(

53、TOLAYER5: data received:);for (i=0; i20; i+)printf(%c,datasenti);printf(n);三、GBN-CS.c#include #include GBN.h” extern int TRACE ;extern int nsim ;*/extern int nsimmax;extern float time;extern int packet_correct;extern int packet_resent;extern struct event *evlist;int main()struct event *eventptr;stru

54、ct msg msg2give;struct pkt pkt2give;int i,j;char c;init();A_init();B_init();while (1)eventptr = evlist;/* for my debugging */ 我的调试/* number of messages from 5 to 4 so far/* for my debugging */ 我的调试/* number of messages from 5 to 4 so far至今为止从从第五到第四的数据信息/* number of msgs to generate, then stop */ 将产生

55、大量的信息,然后结束/* get next event to simulate */ 模拟得到的下一个事件evlist = evlist-next; /* remove this event from event list */移动这个事件到事件表中if (evlist!=NULL)evlist-prev=NULL;if (TRACE = 2)printf(nEVENT time: %f,”,eventptr-evtime);printf( type: %d,eventptr-evtype);if (eventptr-evtype=0)printf(, timerinterrupt );els

56、e if (eventptr-evtype=1)printf(, fromlayer5 ”);elseprintf(, fromlayer3 ”);printf( entity: %dn,eventptr-eventity);time = eventptr-evtime;/* update time to next event time*/更新时间到下一次事件时间if (nsim=nsimmax)break; /* all done with simulation */模拟全部做完if (eventptr-evtype = FROM_LAYER5 )generate_next_arrival(

57、); /* set up future arrival */建立远景到来/* fill in msg to give with string of same letter */填写msg给与串字母都相同j = nsim % 26;for (i=0; i2)printf(MAINLOOP: data given to student:);for (i=0; ieventity = A) (A_output(msg2give);else(B_output(msg2give);else if (eventptr-evtype = FROM_LAYER3)pkt2give.seqnum = eventptr-pktptr-seqnum;pkt2give.acknum = eventptr-pktptr-acknum;pkt2give.checksum = eventptr-pktptr-checksum;for

温馨提示

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

评论

0/150

提交评论