1、网络原理实验报告GBN网络原理实验报告编程模拟GBN姓名: 班级:学号:教师: 1. 实验目的运用各种编程语言实现基于Go-Back-N的可靠数据传输软件。PS:这里使用的是JAVA语言2. 实验意义通过本实验,使学生能够对可靠数据传输原理有进一步的理解和掌握。3. 实验背景Go-Back-N的有限状态机模型表示如下图所示: (a)(b)图为Go-Back-N的有限状态机模型(a)发送端 (b)接受端4. 实验步骤(1) 选择合适的编程语言编程实现基于Go-Back-N的可靠数据传输软件。(2) 在实际网络环境或模拟不可靠网络环境中测试和验证自己的可靠数据传输软件。5. 实验环境(1) 实验语
2、言:JAVA(2) 实验平台:Eclipse(3) 引用库函数:.net库、随机(Random)库、计时库(Timer)6. 类概览与描述(1) Sender类:继承于Thread(线程)类,模拟发送方的 一切功能,主要功能函数有:A Public void run()启动函数,标识开始发送数据包B Sender()构造函数,分配并初始化窗口值C Public void getack(in tack)ACK接收函数,接收接收方返回的ACK并进行验证是否为期待的ACK值(若不是,则重发)D Public void time()定时器函数,初始化定时,计时并记录超时与否的状态(2) Receive
3、r类:继承于Thread(线程)类,模拟接收方的一切功能,主要功能函数有:A Public void run()启动函数,标识开始等待并接收数据包B Void Receive(int data,Sender s)数据包接收函数,功能强大!主要包括:接收数据包,验证数据包,判断与丢弃数据包等C Public void respond(int ack)ACK发送函数,发送当前接收到的最后一次正确的数据包对应的ACK(3) Timers类:继承于TimerTask(计时器)类,具有自定义定时与超时提醒的功能,主要功能函数有:A Public void run()启动函数,标识开始计时(这里预设的是2
4、秒的时间),超时后提醒并且停止计时器B Public Timers()构造函数,清0计时器,等待下一次启动(4) GBN类:继承于Thread(线程)类,是主函数类,具有本程序的核心功能,这里先作一部分简单介绍,主要函数功能有:A Static void senddelay(int x) throws InterruptedExceptionPublic Timers()随机延迟函数,模拟数据包发送传输过程中的随机延迟,常用延迟值分别为:300ms, 750ms, 1200ms, 3000ms等B Public static void main(String args) throws IOEx
5、ception, InterruptedException()主函数,功能强大,主要包含以下几大方面:1 开启发送端与接收端(包括计时器)2 超时或者ACK不匹配等情况导致的发送方 重新发送数据包3 (第一次)发送当前窗口内的数据包4 随机函数模拟数据包发送过程中的丢包情况5 实时更新与显示当前窗口内的数据包情况6 统计每一个数据包被发送过的次数(含重发)并最终显示出来7. 代码展示与描述(一) Sender类import ;public class Sender extends Thread public int windowsize=3; /发送方窗口长度设为3 public String
6、 data=data1,data2,data3,data4,data5,data6,data7; /模拟七个数据包 public int sign=0,1,2,3,4,5,6; /为7个数据包标号 public int localack=-1; /保存最近收到的ACK public Timers litime=null; /定时器(这里定为2秒) public int switches=0; /超时标志,1为超时 public int windowsign; /当前窗口内待发的数据分组的序号public int acksign=0; /为0表示收到正确ACK,为1表示收到错误的ACK,必须重发
7、! public Sender() windowsign=new intwindowsize; /给窗口分配指定大小的空间 for(int i=0;i3;i+) windowsigni=signi; /窗口初始化时存放前3个序号 public void run() 发送方开始发送分组数据!); public void getack(int ack)发送方收到了ACK,序号为+ack+并且开始加以确认!); if(ack!=localack+1)经验证,这不是发送方正期待的ACK,立刻重发序号为+(localack+1)+的数据分组!); acksign=1; else localack=ack
8、; /表示正确确认了ACK acksign=0; public void time() switches=0; /标志初始化为0 litime=new Timers(); Timer limit=new Timer(); limit.schedule(litime, 0,100); (二) Receiver类import ;public class Receiver extends Thread public int lastdata; public Sender sender; public void run(Sender s) sender=s; 接收方开始接收分组数据!); void r
9、eceive(int data, Sender s) sender=s; /发送方的参数传递 接收方收到了序号为+data+的分组!); if(data!=0) if(data=lastdata+1)/数据包序号校验,若连续则是正确/所期待的该数据分组正是接收方所期待的,接收方接受了它并准备回送对应的ACK!); lastdata=data; /更新本地保存的数据包序号变量 respond(lastdata); /回送该正确接收的数据包对应的ACK else该数据分组不是接收方所期待的,该分组将被丢弃,接收方准备回送最后接受的数据分组对应的ACK!); respond(lastdata); /
10、若不是所期待的数据包则丢弃并且重发上一次的ACK else该数据分组正是接收方所期待的,接收方接受了它并准备回送对应的ACK!); lastdata=data; respond(lastdata); /首次接收数据包并且回送ACK void respond(int ack) /回送指定序号的ACK if( /判断是否超时(2秒) ack=lastdata; /获取本场保存的数据包序号 sender.getack(ack); else计时超时!(未丢包但是时间超过2秒)发送方准备重发序号为+ack+的数据分组!); sender.switches=1; /如果超时,设置超时状态并显示警告 (三)
11、 Timers类import ;public class Timers extends TimerTask public int switches; public int limit; public void run() if(limit20) limit+; /计时2秒 else switches=-1; this.cancel(); /开关为-1表示超时,并且停止计时器 public Timers() switches=0; /启动计时器时全部初始化 limit=0; (四) GBN类import .*;import ;import java.io.*;public class GBN e
12、xtends Thread static void senddelay(int x) throws InterruptedExceptionif(x=1) sleep(300); 发送数据分组时发生延迟:300毫秒!); else if(x=2) sleep(750); 发送数据分组时发生延迟:750毫秒!);else if(x=3) sleep(1200);发送数据分组时发生延迟:1200毫秒!);else if(x=4) sleep(3000);发送数据分组时发生延迟:3000毫秒!); else; public static void main(String args) throws I
13、OException, InterruptedException Sender s=new Sender(); Receiver re=new Receiver(); s.start(); /发送端启动 re.run(s); /接收端启动 sleep(1000); /延迟处理 int retimes=new int7; /计算每个分组被发送的次数 for(int i=0;i7;i+) retimesi=0; /数据包顺次发送 for(int i=0;is.localack+1) /尚有未确认的数据包,重发!发送方开始重新发送序号为+(s.localack+1)+的数据分组); retimess
14、.localack+1+; int ran=new Random().nextInt(3); int randelay=new Random().nextInt(5); s.time(); senddelay(randelay); /设置随机值,模拟数据传输延迟 if(ran!=1) re.receive(s.localack+1,s); /设置随机值,模拟数据丢包过程else 序号为+(s.localack+1)+的分组在传给接收方途中发生了丢包!); if(i!= ;发送方现在开始第一次发送序号为+i+的数据分组); retimesi+; if(i!=0) for(int k=0;k3;k
15、+) /表示至少成功发送并确认了一个数据分组 s.windowsignk+; /这种情况下滑动窗口向前移动! ; 当前窗口内的分组情况为:); /显示当前窗口内数据包情况 for(int p=0;p3;p+) if(s.windowsignp=6)第+p+号窗口里面存放的是序号为+s.windowsignp+的马上待发送的数据分组!); else第+p+号窗口已经空了,并且后续窗口、发送方没有要发送的数据分组了!); ; int ran=new Random().nextInt(3); int randelay=new Random().nextInt(5); s.time(); /计时开始(2秒时间) senddelay(randelay); /设置随机值,模拟数据传输延迟 if(ran!=1) re.receive(s.signi,s); /设置随机值,模拟数据丢包过程 else 序号为+i+的分组在传给接收方途中发生了丢包!); ;以下是每个数据分组被发送过的次数的统计结果); for(int i=0;i7;i+) /显示关于每个数据包发送次数的统计表序号为+i+的数据分组被发送过的次数为: +retimesi); System.exit(0); 8. 程序运行结果部分截图PS:随机选择了某次程序运行后结果显示的部分截图
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1