📄 server_start.java
字号:
/**
*协议的服务器端启动状态.
*是Server_State状态的下一个状态
*执行它的doIt方法,并转入下一个状态
*/
import java.io.IOException;
import java.util.Timer;
public class Server_Start extends State {
public static FileIOClass myfile;//将要发送或存储的文件
public static ComClass Com; //用于传输
Timer timer = new Timer(false);
State doIt() {
System.out.println("服务器端启动 -- 简单FTP (基于TFTP协议) \n\n");
System.out.println("......\n");
System.out.println("当前服务器的目录为:" + "c:\\Sftp.dir ");
Com = new ComClass(69);
myfile = new FileIOClass();
byte[] buffer = Com.receivePacket(); //接受请求
while(buffer[1]!=PacketCode.WRQ&&buffer[1]!=PacketCode.RRQ) {
System.out.println("收到了一个错误的请求,继续等待...");
buffer = Com.receivePacket();
}
Com.addr = Com.giveLastPacketAddress() ; //C的地址
if(buffer[0]==0 && buffer[1]==PacketCode.RRQ) { //接受读请求01
int n = 0; //得到文件名的长度
for(int i=2;i<516;i++) {
if(buffer[i]==0) {
n = i;
break;
}
}
String filename = new String(buffer,2,n-2); //从中得到文件名
byte filemode = myfile.openFile("c:\\Sftp.dir\\"+filename); //打开要发给C的文件
if(filemode==FileIOClass.open_failed) { //打开不成功则返回Server_Start状态
System.exit(0);
Com.sendPacketERR((byte)0,PacketCode.ERROR,"1 文件未找到!");
this.next_state = new Server_Start(); ///???
return this.next_state;
}
byte num = 1 ;
boolean endsLoop = false;
while(endsLoop == false) {
byte [] filedata = myfile.readFromFile();
DataDelayClass Datadelay = new DataDelayClass(filedata,num);
Datadelay.start();
buffer = Com.receivePacket();
while(buffer[1]!=PacketCode.ACK ||buffer[3]!=num) {
System.out.println("收到了错误的ACK的包,保持等待!");
buffer = Com.receivePacket() ;
}
Datadelay.task.cancel();
timer.purge();
num += 1 ;
if(num == 126) { //1 -- 125
num = 1;
}
if(filedata[511]==1) { //如果传文件结束的话,结束整个发送循环
endsLoop = true ;
System.out.println("文件传送结束.");
}
}
}
else if(buffer[0]==0 && buffer[1]==PacketCode.WRQ) {//接受写请求02
int n = 0;
for(int i=2;i<516;i++) { //文件名的长度
if(buffer[i]==0) {
n = i;
break;
}
}
String filename = new String(buffer,2,n-2); //从中得到文件名
byte filemode = myfile.createFile("c:\\Sftp.dir\\"+filename+".n"); //新建文件
//测试,如果文件建立失败的话.....
if(filemode == FileIOClass.already_exists) {
Com.sendPacketERR((byte)0,PacketCode.ERROR,"6 文件已经存在!");
System.out.println("文件已经存在!");
this.next_state = new Server_Start();///???这里应该直接退出程序
return this.next_state;
}
if(filemode == FileIOClass.create_failed) {
Com.sendPacketERR((byte)0,PacketCode.ERROR,"0 文件创建失败!");
System.out.println("文件创建失败!");
this.next_state = new Server_Start();///???这里应该直接退出程序
return this.next_state;
}
boolean endsLoop = false;
byte num = 0;
while(endsLoop == false) {
WDelayClass Wdelay = new WDelayClass(num);//发ACK包任务,第一个是对WRQ的响应
Wdelay.start();
if(num == 125) {
num = 0 ;
}
byte [] bufrev = Com.receivePacket();//收包,且包是正确的
while(bufrev[1]!=PacketCode.DATA||bufrev[3]!=num+(byte)1) {
bufrev = Com.receivePacket();
}
Wdelay.task.cancel();
timer.purge();
myfile.writeToFile(bufrev);
num += 1 ;
if(bufrev[515] == 1) { //如果是最后一个包
myfile.endWrite() ;
endsLoop = true ;
}
}
System.out.print("发送最后一个ACK包:");
Com.sendPacketACK((byte)0,num);
}
Com.closeSocket();
this.next_state = new Idle();
return this.next_state;
}
//发送ACK包的线程,对写请求的响应
public class WDelayClass extends java.lang.Thread {
WResendClass task ;
byte num ;
public WDelayClass(byte num) {
this.num = num ;
}
public void run() {
task = new WResendClass(num);
timer.schedule(task,0 ,2000);
}
}
//超时重发ACK包的线程
public class WResendClass extends java.util.TimerTask {
final long time = System.currentTimeMillis();//date.getTime();
byte num ;
public WResendClass(byte num) {
this.num = num ;
}
public void run() {
Server_Start.Com.sendPacketACK((byte)0,num); //发送数据报
if (System.currentTimeMillis() - time >= 10000) {
this.cancel();
timer.purge();
System.out.println("等待超时!");
// System.exit(0);
}
}
}
//发送数据包的线程
public class DataDelayClass extends java.lang.Thread {
byte[] filedata ;
byte num ;
DataResendClass task ;
public DataDelayClass(byte[] filedata,byte num) {
this.filedata = filedata ;
this.num = num ;
task = new DataResendClass(filedata, num);
}
public void run() {
timer.schedule(task,0 ,2000);
}
}
//超时重发数据包的线程
public class DataResendClass extends java.util.TimerTask {
byte[] filedata ;
byte num ;
final long time = System.currentTimeMillis();//date.getTime();
public DataResendClass(byte[] filedata,byte num) {
this.filedata = filedata ;
this.num = num ;
}
public void run() {
Server_Start.Com.sendPacketDATA(filedata,(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 + -