编程实现可靠数据传输原理GO-BACK-N实验姓名:吴杰学号:13281144班级:计科1306一.实验目的运用各种变成语言实现基于Go-Back-N的可靠数据传输软件二.实验意义通过本实验,使学生能够对可靠数据传输原理有进一步的理解和掌握。三.实验步骤1.利用java编程实现基于Go-Back-N的可靠数据传输软件。2.运行程序,程序将模拟实际网络中的可靠数据传输四.结果分析通过本次实验,了解了GBN传输协议的相关知识。实验代码通过查阅资料很容易理解,但是怎么实现这个程序对我来说是个问题。五.附件JAVA语言代码(1)Sender类packageGBN;importjava.util.Timer;publicclassSenderextendsThread{publicintwindowsize=3;//发送方窗口长度设为3publicString[]data={data1,data2,data3,data4,data5,data6,data7};//模拟七个数据包publicintsign[]={0,1,2,3,4,5,6};//为7个数据包标号publicintlocalack=-1;//保存最近收到的ACKpublicTimerslitime=null;//定时器(这里定为2秒)publicintswitches=0;//超时标志,1为超时publicintwindowsign[];//当前窗口内待发的数据分组的序号publicintacksign=0;//为0表示收到正确ACK,为1表示收到错误的ACK,必须重发!publicSender(){windowsign=newint[windowsize];//给窗口分配指定大小的空间for(inti=0;i3;i++)windowsign[i]=sign[i];//窗口初始化时存放前3个序号}publicvoidrun(){System.out.println(发送方开始发送分组数据!);}publicvoidgetack(intack){System.out.println(发送方收到了ACK,序号为+ack+并且开始加以确认!);if(ack!=localack+1){System.out.println(经验证,这不是发送方正期待的ACK,立刻重发序号为+(localack+1)+的数据分组!);acksign=1;}else{localack=ack;//表示正确确认了ACKacksign=0;}}publicvoidtime(){switches=0;//标志初始化为0litime=newTimers();Timerlimit=newTimer();limit.schedule(litime,0,100);}}(2)Receiver类packageGBN;publicclassReceiverextendsThread{publicintlastdata;publicSendersender;publicvoidrun(Senders){sender=s;System.out.println(接收方开始接收分组数据!);}voidreceive(intdata,Senders){sender=s;//发送方的参数传递System.out.println(接收方收到了序号为+data+的分组!);if(data!=0){if(data==lastdata+1){//数据包序号校验,若连续则是正确/所期待的System.out.println(该数据分组正是接收方所期待的,接收方接受了它并准备回送对应的ACK!);lastdata=data;//更新本地保存的数据包序号变量respond(lastdata);//回送该正确接收的数据包对应的ACK}else{System.out.println(该数据分组不是接收方所期待的,该分组将被丢弃,接收方准备回送最后接受的数据分组对应的ACK!);respond(lastdata);//若不是所期待的数据包则丢弃并且重发上一次的ACK}}else{System.out.println(该数据分组正是接收方所期待的,接收方接受了它并准备回送对应的ACK!);lastdata=data;respond(lastdata);//首次接收数据包并且回送ACK}}voidrespond(intack){//回送指定序号的ACKif(sender.litime.limit20){//判断是否超时(2秒)ack=lastdata;//获取本场保存的数据包序号sender.getack(ack);}else{System.out.println(计时超时!!(未丢包但是时间超过2秒)发送方准备重发序号为+ack+的数据分组!);sender.switches=1;//如果超时,设置超时状态并显示警告}}}(3)Timers类packageGBN;importjava.util.TimerTask;publicclassTimersextendsTimerTask{publicintswitches;publicintlimit;publicvoidrun(){if(limit20)limit++;//计时2秒else{switches=-1;this.cancel();}//开关为-1表示超时,并且停止计时器}publicTimers(){switches=0;//启动计时器时全部初始化limit=0;}}(4)GBN类packageGBN;importjava.util.Random;importjava.io.*;publicclassGBNextendsThread{staticvoidsenddelay(intx)throwsInterruptedException{if(x==1){sleep(300);System.out.println(发送数据分组时发生延迟:300毫秒!);}elseif(x==2){sleep(750);System.out.println(发送数据分组时发生延迟:750毫秒!);}elseif(x==3){sleep(1200);System.out.println(发送数据分组时发生延迟:1200毫秒!);}elseif(x==4){sleep(3000);System.out.println(发送数据分组时发生延迟:3000毫秒!);}}publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{Senders=newSender();Receiverre=newReceiver();s.start();//发送端启动re.run(s);//接收端启动sleep(1000);//延迟处理int[]retimes=newint[7];//计算每个分组被发送的次数for(inti=0;i7;i++)retimes[i]=0;//数据包顺次发送for(inti=0;i=s.sign.length;i++){while(is.localack+1){//尚有未确认的数据包,重发!System.out.println(发送方开始重新发送序号为+(s.localack+1)+的数据分组);retimes[s.localack+1]++;intran=newRandom().nextInt(3);intrandelay=newRandom().nextInt(5);s.time();senddelay(randelay);//设置随机值,模拟数据传输延迟if(ran!=1)re.receive(s.localack+1,s);//设置随机值,模拟数据丢包过程elseSystem.out.println(序号为+(s.localack+1)+的分组在传给接收方途中发生了丢包!);}if(i!=s.sign.length){System.out.println();System.out.println(发送方现在开始第一次发送序号为+i+的数据分组);retimes[i]++;if(i!=0){for(intk=0;k3;k++){//表示至少成功发送并确认了一个数据分组s.windowsign[k]++;//这种情况下滑动窗口向前移动!}}System.out.println();System.out.println(当前窗口内的分组情况为:);//显示当前窗口内数据包情况for(intp=0;p3;p++){if(s.windowsign[p]=6)System.out.println(第+p+号窗口里面存放的是序号为+s.windowsign[p]+的马上待发送的数据分组!);elseSystem.out.println(第+p+号窗口已经空了,并且后续窗口、发送方没有要发送的数据分组了!);}System.out.println();intran=newRandom().nextInt(3);intrandelay=newRandom().nextInt(5);s.time();//计时开始(2秒时间)senddelay(randelay);//设置随机值,模拟数据传输延迟if(ran!=1)re.receive(s.sign[i],s);//设置随机值,模拟数据丢包过程elseSystem.out.println(序号为+i+的分组在传给接收方途中发生了丢包!);}}System.out.println();System.out.println(以下是每个数据分组被发送过的次数的统计结果);for(inti=0;i7;i++)//显示关于每个数据包发送次数的统计表System.out.println(序号为+i+的数据分组被发送过的次数为:+retimes[i]);System.exit(0);}}