📄 client_get.java
字号:
/**
*协议的Client_Get状态.
*/
import java.util.Timer;
import java.io.FileInputStream;
public class Client_Get extends State {
public static FileIOClass myfile;//将要存储的文件名
public static ComClass Com; //用于传输
Timer timer = new Timer(false);
State doIt() {
String addr, file;
SimpleIO input = new SimpleIO(System.in);
System.out.println("请输入文件名:\n");
file = input.readString();
System.out.println("请输入服务器IP:\n");
addr = input.readString();
Com = new ComClass(5555);
FileIOClass myfile = new FileIOClass();
byte filemode = myfile.createFile(file+".n"); //创建一个新的文件
if(filemode==FileIOClass.already_exists||
filemode==FileIOClass.create_failed) { //打开不成功则返回Client_Put状态
this.next_state = new Client_Get(); ///???
return this.next_state;
}
Com.writeOtherSiteAddress(addr); //记下服务器IP
byte num = 1 ;
RWDelayClass Rdelay = new RWDelayClass(file);//发送RRQ的任务线程
Rdelay.start();
byte[] revbuf = Com.receivePacket() ;
//如果不是DATA包或者对方相应的序号错
while(revbuf[1]!=PacketCode.DATA ||revbuf[3]!=num) {
System.out.println("收到了错误的DATA包,保持等待!");
revbuf = Com.receivePacket() ;
}
Rdelay.task.cancel();//取消任务
timer.purge(); //移除任务
myfile.writeToFile(revbuf);
boolean endsLoop = false;
while( endsLoop == false) {
ACKDelayClass ACKdelay = new ACKDelayClass(num);//发送ACK的任务线程
ACKdelay.start() ;
if(num == 125) {
num = 0 ;
}
revbuf = Com.receivePacket();
while(revbuf[1]!=PacketCode.DATA||revbuf[3]!=num+(byte)1) {
System.out.println("收到了错误的DATA的包,保持等待!");
revbuf = Com.receivePacket() ;
}
ACKdelay.task.cancel();
timer.purge();
myfile.writeToFile(revbuf);
num += 1;
if(revbuf[515] == 1) { //如果是最后一个包
endsLoop = true ;
myfile.endWrite() ;
}
}
System.out.print("发送最后一个ACK包:");
Com.sendPacketACK((byte)0,num);
Com.closeSocket();
this.next_state = new Idle();
return this.next_state;
}
//发送读请求包的线程
public class RWDelayClass extends java.lang.Thread {
String filename ;
RWResendClass task ;
public RWDelayClass(String filename) {
this.filename = filename ;
task = new RWResendClass(filename);
}
public void run() {
timer.schedule(task,0 ,2000);
}
}
//超时重发读请求包的线程
public class RWResendClass extends java.util.TimerTask {
String filename ;
final long time = System.currentTimeMillis();//date.getTime();
public RWResendClass(String filename) {
this.filename = filename ;
}
public void run() {
Client_Get.Com.sendPacketRW(filename,(byte)0,PacketCode.RRQ); //发送数据报
if (System.currentTimeMillis() - time >= 10000) {
this.cancel();
timer.purge();
System.out.println("等待超时!");
System.exit(0);
}
}
}
//发送ACK的线程
public class ACKDelayClass extends java.lang.Thread {
byte num ;
ACKResendClass task ;
public ACKDelayClass(byte num) {
this.num = num ;
task = new ACKResendClass(num);
}
public void run() {
timer.schedule(task,0 ,2000);
}
}
//超时重发ACK包的线程
public class ACKResendClass extends java.util.TimerTask {
byte num ;
final long time = System.currentTimeMillis();//date.getTime();
public ACKResendClass(byte num) {
this.num = num ;
}
public void run() {
Client_Get.Com.sendPacketACK((byte)0,num); //发送数据报
if (System.currentTimeMillis() - time >= 10000) {
this.cancel();
timer.purge();
System.out.println("等待超时!");
System.exit(0);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -