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

📄 tftp.java

📁 JAVA编写的tftp软件
💻 JAVA
字号:

import java.net.*;
import java.io.*;
import java.util.*;

public class tftp {
	static File f=null;
	static int debug=2;
	static int flag;//Print flag
	//下载上传目录:
	static String path="d://javawork//testfile//";
	
	//端口号
	static DatagramSocket ds;
	static byte[] buf=new byte[516];
	static DatagramPacket dp=new DatagramPacket(buf,516);
	
    //	请求包的数据结构
    static short opcode = 0;
	static String filename=new String();
	static String mode=new String();
	
    //	数据包的数据结构
	static short tftp_opcoded=3;
	static Short blockd=1;
	static String data=new String();
	
    //	ack包的结构
	static Short blocka=0;
	/*short tftp_opcodeq;*/
	
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		
		 //端口定义
		 ds=new DatagramSocket(69);	
		
		while(true){
		//reset ...
		blockd=1;
		blocka=0;
		
			
			for(;;){
            //输入流
			DataInputStream din = null;
		    
		        ds.receive(dp);
		       
			buf = dp.getData(); 
			din = new DataInputStream(new ByteArrayInputStream(buf));
			
			//get operate code
			opcode = din.readShort();  
			 Println(debug,opcode,dp.getAddress(),flag);
			//get filename
            int foffset=2;//offset point to filename
            int flen=0;//count the length of filename
            while(din.readByte()!=0)
            {
                flen++; //filename will end with a null char('\0')
            }
            filename=new String(buf,foffset,flen);

            //get the mode   
            int mdnoffset=foffset+flen+2;
            int mdnlen=0;
            while (din.readByte()!=0) 
            {
                mdnlen++; //filename will end with a null char('\0')
            }
           mode = new String(buf,mdnoffset,mdnlen);
           
           if(opcode==1){
        	   RunRQ();//recieved read/download request.execute download method
        	   break;//break for(;;) execute while();
           }
               else{//opcode==2
        	        RunWQ();//recieved write/upload request.execute upload method
        	        break;//break for(;;)
                   }//end branch(opcode==1)
		}//end for(;;)
		
		
		

	}//end while(); never break

}//end main()
	public static void RunRQ() throws Exception{
		flag=1;
		long filepointer=1;
	    RandomAccessFile rf=null;
		f=new File(path+filename);
		
		if(f.exists()){//file is allowed to download
		    rf=new RandomAccessFile(f,"r");
		    long filelength=rf.length();//get the length of file
		    long num=filelength/512+1;//get the number of block will be send
		    
		    //send data(1)
		    //输出流
	        ByteArrayOutputStream bag=new ByteArrayOutputStream();
	        DataOutputStream dout=new DataOutputStream(bag);
	        byte[] b=new byte[512];
	        dout.writeShort(3); //the opcode: data
            dout.writeShort(blockd);    //the block number
            
	        if(filepointer<num){
        		rf.seek((filepointer-1)*512);
        		rf.read(b);
        		dout.write(b); 
        		//data=new String(b,0,512);
        	}else{  
        	         if(filepointer==num){
        	         	long len=filelength%512;
        	         	int lenint=(int)len;
        	         	byte[] b2=new byte[lenint];
        	         	rf.seek((filepointer-1)*512);
        		        rf.read(b2);
        		        dout.write(b2); 
        	         }  else{ 		
        		             System.out.println("Download file "+filename+" sccuessful!");
        		             rf.close();   
        		             return;
        	                }
        	      } //end check data(1) wether the last data packet,and data(1) was writen in DataOutputStream dout      
        	rf.close(); 
        	//send data(1)
        	ds.send(new DatagramPacket(bag.toByteArray(), bag.size(),dp.getAddress(),dp.getPort()));   
        	Println(debug,3,dp.getAddress(),flag);
  
        	//start receiving ack
        	for(;;){
        		
        		rf=new RandomAccessFile(f,"r");
        		//输入流
		        DataInputStream din = null;
		        //输出流
	             ByteArrayOutputStream bag2=new ByteArrayOutputStream();
	             DataOutputStream dout2=new DataOutputStream(bag2);
	    
	    	
	            ds.receive(dp);
	            
		        buf = dp.getData(); 
		        din = new DataInputStream(new ByteArrayInputStream(buf));
		        opcode = din.readShort();  //得到操作码
		        Println(debug,opcode,dp.getAddress(),flag);
		        
		         if(opcode==4)//if recieve ack
		         {
		         	 
			         blocka=din.readShort(); //read block of ack
			         //if(blocka==9)blockd--;
			         if(blockd.equals(blocka)){//copare with block data.if equal to block of data which sended,blockd++ ready to send next data
			             if(blockd==32767){//block最大表示范围
				             blockd=1;
			             }else{
					         blockd++;
			                   }//end check blockd==32767
			
			             filepointer++;//文件指针下移
			          }//end blockd.equals(blocka)  
			          //send data
			          dout2.writeShort(3); //the opcode: data
                      dout2.writeShort(blockd);    //the block number
                      
	                  if(filepointer<num){
        		           rf.seek((filepointer-1)*512);
        		           rf.read(b);
        		           dout2.write(b); 
        		//data=new String(b,0,512);
        	          }else{  
        	                 if(filepointer==num){        
        	         	          rf.seek((filepointer-1)*512);
        	         	          long len2=filelength%512;
        	         	          int lenint2=(int)len2;        	         	                 	         	          
        	         	          byte[] b2=new byte[lenint2];
        		                  rf.read(b2);
        		                  dout2.write(b2); 
        	                      } else{ 		
        		                    System.out.println("Download file "+filename+" sccuessful!");
        		                    rf.close();   
        		                    return;
        	                              }
        	      } //end check data(blockd) wether the last data packet,and data(blockd) was writen in DataOutputStream dout      
        	rf.close(); 
        	//send data(blockd)
        	ds.send(new DatagramPacket(bag2.toByteArray(), bag2.size(),dp.getAddress(),dp.getPort()));   
            Println(debug,3,dp.getAddress(),flag);
			       }//end if(opcode==4)
			       else{//opcode=1 data(1) is still in bag
			       ds.send(new DatagramPacket(bag.toByteArray(), bag.size(),dp.getAddress(),dp.getPort())); 
			       Println(debug,3,dp.getAddress(),flag); 
			       }  	        
      }//end for(;;)
		}else{//file is not exists ,can't download
		    String ErrMsg="error:file not found";
			int value=1;
			SendError(value,ErrMsg,dp.getAddress(),dp.getPort());
		}//end of check whether file is exist
		return;
	}//end RunRQ
	
	
	public static void RunWQ()throws Exception{
		flag=0;
	    long filepointer=0;
	    RandomAccessFile wf=null;
		f=new File(path+filename);
		if(!f.exists()){//file is allowed to upload
			//send ack(0)
			SendAck(blocka,dp.getAddress(),dp.getPort());
			Println(debug,4,dp.getAddress(),flag);
			//waiting to receive packet(data or write request)
			
			for(;;){
				// 输入流
    		DataInputStream din = null;
            buf = dp.getData(); 
			din = new DataInputStream(new ByteArrayInputStream(buf));
			
			//receive packet
			ds.receive(dp);
		
			
            
            //timeout doesn't occur,so received the packet,get operate code
            
			//get operate code
			opcode = din.readShort();
			Println(debug,(int)opcode,dp.getAddress(),flag);
			if(opcode==3){//packet is data packet
                //read data 
				blockd=din.readShort(); //read block of data
				byte[] bufdata=new byte[512];
				din.read(bufdata);//read data
				data=new String(bufdata);
				blockd--;
				if(blocka.equals(blockd)){//copare with block data.if equal to block of data which recieved,resend this ack,else ready to recieve next data
				//blocka++ filepointer++
				blocka++;
				filepointer++;
				    if(blocka==1){//createfile
                    //create file
				      f.createNewFile();
                    //write file
				      try{
				           wf=new RandomAccessFile(f,"rw");
				      }
				      catch (FileNotFoundException ex) {
		                     break ;
		                 }
				      wf.write(bufdata);
                    //send ack
			    	  SendAck(blocka,dp.getAddress(),dp.getPort());	
			    	  Println(debug,4,dp.getAddress(),flag);
				      if(dp.getLength()<512){//the last packet				      	
	                      System.out.println("Host send last ack:"+blocka);				
					      System.out.println("Upload file "+filename+" sccuessful!");					         
					      break; 
				                             }//end check last packet
				      //if dp.getLength()=512
				                 }//end blocka==1;
				                 else{//blocka>1
				                //write file
				                 try{
				                	  wf=new RandomAccessFile(f,"rw");
				                 }
				                 catch (FileNotFoundException ex) {
				                     break ;
				                 }
				                 wf.seek((filepointer-1)*512);
				                 wf.write(bufdata);
				                 //send ack
				                 SendAck(blocka,dp.getAddress(),dp.getPort());	
				                 Println(debug,4,dp.getAddress(),flag);
				                 if(dp.getLength()<512){				                 	
	                                  System.out.println("The last block of data is:"+blocka);
					                  System.out.println("Upload file"+filename+"sccuessful!");
					                  break;
				                                       }//end check last packet
                                  //if dp.getLength()==512
							     
				                 }//end check block==1
					

				}//recieved right data,write it in file.可以发送ack了
			}else{//packet is write request packet,that means ack(0) was lost,so send ack(0) again.
				SendAck(blocka,dp.getAddress(),dp.getPort());
				Println(debug,4,dp.getAddress(),flag);
			     }//end check opcode(data or write request)
			}//end for(;;)
			}else{//file already exists
			String ErrMsg="error:file already exists";
			int value=6;
			SendError(value,ErrMsg,dp.getAddress(),dp.getPort());
		        }//end check file
		        return;
	}//end RunRQ
	
	public static void SendAck(short blockack,InetAddress addr,int port)throws Exception{
        //		输出流
	    ByteArrayOutputStream bag=new ByteArrayOutputStream();
	    DataOutputStream dout=new DataOutputStream(bag);
	    dout.writeShort(4);
	    dout.writeShort(blockack);
	    byte[] bufack=bag.toByteArray();
	    DatagramPacket ackpacket = new DatagramPacket(bufack,bufack.length,addr,port);
        ds.send(ackpacket);
	}//end SendAck
	
	public static void SendError(int value,String Msg,InetAddress addr,int port)throws Exception{
		ByteArrayOutputStream bag=new ByteArrayOutputStream();
	    DataOutputStream dout=new DataOutputStream(bag);
	    dout.writeShort(5);
	    dout.writeShort(value);
        dout.write(Msg.getBytes());
        dout.writeByte(0);  //end of the ErrMsg
        byte[] bufERROR = bag.toByteArray();
        //construct a UDP packet 
         DatagramPacket dpError = new DatagramPacket(bufERROR,bufERROR.length,addr,port);
         ds.send(dpError);
         if(debug==2||debug==1)
         System.out.println("Error "+Msg);
	}//end SendError
	
	public static void Println(int debug,int opcode,InetAddress addr,int flag){//flag=0 uploader receive data send ack;flag=1,download send data receive ack
		if(opcode==1){
			System.out.print(new Date());
			System.out.println(" receive RRQ from "+addr.toString());
		}
		if(opcode==2){
			System.out.print(new Date());
			System.out.println(" receive WRQ from "+addr.toString());
		}
		if(opcode==3&&flag==0&&debug==2){
			System.out.print(new Date());
			System.out.println(" receive DATA from "+addr.toString());
		}
		if(opcode==3&&flag==1&&debug==2){
			System.out.print(new Date());
			System.out.println(" send DATA to"+addr.toString());
		}
		if(opcode==4&&flag==0&&debug==2){
			System.out.print(new Date());
			System.out.println(" send ACK to "+addr.toString());
		}
		if(opcode==4&&flag==1&&debug==2){
			System.out.print(new Date());
			System.out.println(" receive ACK from "+addr.toString());
		}
	}//end Println();
}//end class

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -