⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server_start.java

📁 用java写的SFTP代码
💻 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 + -