编程实现可靠数据传输原理GO-BAN-N实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

编程实现可靠数据传输原理GO-BACK-N实验
姓名:吴杰学号:13281144 班级:计科1306
一.实验目的
运用各种变成语言实现基于Go-Back-N的可靠数据传输软件
二.实验意义
通过本实验,使学生能够对可靠数据传输原理有进一步的理解和掌握。

三.实验步骤
1.利用java编程实现基于Go-Back-N的可靠数据传输软件。

2.运行程序,程序将模拟实际网络中的可靠数据传输
四.结果分析
通过本次实验,了解了GBN传输协议的相关知识。

实验代码通过查阅资料很容易理解,但是怎么实现这个程序对我来说是个问题。

五.附件
JAVA语言代码
(1)Sender类
package GBN;
import java.util.Timer;
public class Sender extends Thread{
public int windowsize=3; //发送方窗口长度设为3
public String[] 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,必须重发!
public Sender(){
windowsign=new int[windowsize]; //给窗口分配指定大小的空间
for(int i=0;i<3;i++)
windowsign[i]=sign[i]; //窗口初始化时存放前3个序号
}
public void run(){
System.out.println("发送方开始发送分组数据!");
}
public void getack(int ack){
System.out.println("发送方收到了ACK,序号为"+ack+"并且开始加
以确认!");
if(ack!=localack+1){
System.out.println("经验证,这不是发送方正期待的ACK,立刻重
发序号为"+(localack+1)+"的数据分组!");
acksign=1;
}
else{
localack=ack; //表示正确确认了ACK
acksign=0;
}
}
public void time(){
switches=0; //标志初始化为0
litime=new Timers();
Timer limit=new Timer();
limit.schedule(litime, 0,100);
}
}
(2)Receiver类
package GBN;
public class Receiver extends Thread{
public int lastdata;
public Sender sender;
public void run(Sender s){
sender=s;
System.out.println("接收方开始接收分组数据!");
}
void receive(int data, Sender s){
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 }
}
void respond(int ack){ //回送指定序号的ACK if(sender.litime.limit<20){ //判断是否超时(2秒)ack=lastdata; //获取本场保存的数据包序号
sender.getack(ack);
}
else{
System.out.println("计时超时!!(未丢包但是时间超过2秒)发送方准备重发序号为"+ack+"的数据分组!");
sender.switches=1; //如果超时,设置超时状态并显示警告
}
}
}
(3)Timers类
package GBN;
import java.util.TimerTask;
public class Timers extends TimerTask {
public int switches;
public int limit;
public void run(){
if(limit<20) limit++; //计时2秒
else {
switches=-1;
this.cancel();
} //开关为-1表示超时,并且停止计时器
}
public Timers(){
switches=0; //启动计时器时全部初始化
limit=0;
}
}
(4)GBN类
package GBN;
import java.util.Random;
import java.io.*;
public class GBN extends Thread{
static void senddelay(int x) throws InterruptedException{
if(x==1) {
sleep(300);
System.out.println("发送数据分组时发生延迟:300毫秒!");
}
else if(x==2) {
sleep(750);
System.out.println("发送数据分组时发生延迟:750毫秒!");
}
else if(x==3) {
sleep(1200);
System.out.println("发送数据分组时发生延迟:1200毫秒!");
}
else if(x==4) {
sleep(3000);
System.out.println("发送数据分组时发生延迟:3000毫秒!");
}
}
public static void main(String[] args) throws IOException, InterruptedException { Sender s=new Sender();
Receiver re=new Receiver();
s.start();//发送端启动
re.run(s);//接收端启动
sleep(1000);//延迟处理
int[] retimes=new int[7]; //计算每个分组被发送的次数
for(int i=0;i<7;i++)
retimes[i]=0;//数据包顺次发送
for(int i=0;i<=s.sign.length;i++){
while(i>s.localack+1){//尚有未确认的数据包,重发!
System.out.println("发送方开始重新发送序号为"+(s.localack+1)+"的数据分组");
retimes[s.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
System.out.println("序号为"+(s.localack+1)+"的分组在传给接收方途中发生了丢包!");
}
if(i!=s.sign.length){
System.out.println();
System.out.println("发送方现在开始第一次发送序号为"+i+"的数据分组");
retimes[i]++;
if(i!=0){
for(int k=0;k<3;k++){
//表示至少成功发送并确认了一个数据分组
s.windowsign[k]++;
//这种情况下滑动窗口向前移动!
}
}
System.out.println();
System.out.println("当前窗口内的分组情况为:");
//显示当前窗口内数据包情况
for(int p=0;p<3;p++){
if(s.windowsign[p]<=6)
System.out.println("第"+p+"号窗口里面存放的是序号为"+s.windowsign[p]+"的马上待发送的数据分组!");
else
System.out.println("第"+p+"号窗口已经空了,并且后续窗口、发送方没有要发送的数据分组了!");
}
System.out.println();
int ran=new Random().nextInt(3);
int randelay=new Random().nextInt(5);
s.time();//计时开始(2秒时间)
senddelay(randelay);//设置随机值,模拟数据传输延迟
if(ran!=1) re.receive(s.sign[i],s);
//设置随机值,模拟数据丢包过程
else System.out.println("序号为"+i+"的分组在传给接收方途中发生了丢包!");
}
}
System.out.println();System.out.println("以下是每个数据分组被发送过的次数的统计结果");
for(int i=0;i<7;i++)//显示关于每个数据包发送次数的统计表
System.out.println("序号为"+i+"的数据分组被发送过的次数为:"+retimes[i]);
System.exit(0);
}
}。

相关文档
最新文档