-1
package experiments; 

import java.io.*;

 import java.net.Socket; 
/** * * @author User */ 

/*THE CLIENT*/ public class UploadManager { 

public static void setup(String address, int port,String path){ 

try( Socket s = new Socket(address,port); OutputStream out = s.getOutputStream(); InputStream in = s.getInputStream(); DataOutputStream dos = new DataOutputStream(out); 
DataInputStream dis = new DataInputStream(in); )

{ 
/** * send file name and size to server */ 
System.out.println("processing file now"); 

File from = new File(path); 

if(from.exists() && from.canRead()){ 

String FILENAME = from.getName(); 

long FILESIZE = from.length();
 // String FILEHASH 

 /** * write all ,2 * to SERVER */ dos.writeLong(FILESIZE); dos.writeUTF(FILENAME);
 //dos.writeUTF(FILEHASH); 
dos.flush(); 

/** * what does SERVER HAS TO SAY? */

 String RESPONSE_FROM_SERVER_1 =dis.readUTF();
 if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("SEND")){ 
uploadFresh(from,dos); 
}   
    /** * in case there was an interruption we need * resume from an offset. */ 

        if(RESPONSE_FROM_SERVER_1 . equalsIgnoreCase("RESUME")){

 /** * length already sent */

 System.out.println("resuming upload"); 

String LENGTH_ALREADY_READ =dis.readUTF(); 

long OFF_SET = Long.parseLong(LENGTH_ALREADY_READ); 

/** * get the file name so we know the exact file */ 

String FILE_REAL_NAME = dis.readUTF(); 

resume(FILE_REAL_NAME,OFF_SET,dos);
 } 
}else{ System.out.println("Couldn't read: err"); 

} 

}catch(Exception ex){ 
ex.printStackTrace(); 
}
 }
 /** the resume method **/ 

private static void resume(String FILE_REAL_NAME,long OFF_SET,DataOutputStream to)throws Exception{ 

/** * copy from the stream or disk to server */ 

FileInputStream reader = null; 

try{
 reader = new FileInputStream(new File("c:\\movies\\hallow.mp4",FILE_REAL_NAME)); byte[] size = new byte [8192]; 

int COUNT_BYTES_READ ; reader.skip(OFF_SET);

//skip the length already written

 while( (COUNT_BYTES_READ = reader.read(size)) >0{ 

to.write(size); 
to.flush();
 } 
}finally{ 
if( reader != null ) reader.close();

 to.close(); 

}
 } 

/** and the normal send method which works as expected **/ 

private static void uploadFresh(File from, DataOutputStream to)throws Exception{

 /** * copy from the stream or disk to server */ 
FileInputStream reader = null;
 try{ 
reader = new FileInputStream(from); 
byte[] size = new byte [1024];
 int COUNT_BYTES_READ ; 

while( (COUNT_BYTES_READ = reader.read(size)) >0){

 to.write(size,0,COUNT_BYTES_READ); to.flush(); 
} 
}finally{ 
if( reader != null ) reader.close();

 to.close(); 
}
 } 
}

//ThE SERVER

public class UserServer { 
String ip_Adress; 
int Port; 
ServerSocket ss; 
String path;

public UserServer(String ip_Adress,int Port ){
 this.Port =Port; this.ip_Adress = ip_Adress; this. path = path;
 } 

public void startserver() throws IOException{
 FileOutputStream fos =null; 
// String realhash; 
out.println("starting server"); 

this.ss= new ServerSocket(Port);
 out.println("starting server on port"+Port); out.println("waiting for client conection......"); 

Socket visitor = this.ss.accept(); 

out.println("1 User connected to port");

 /** 
* reading file name and size from upload 
*/ 
try( OutputStream ot =visitor.getOutputStream(); InputStream in = visitor.getInputStream(); DataOutputStream dos = new DataOutputStream(ot); DataInputStream dis = new DataInputStream(in); ){ 

System.out.println("processing debug"); 
long FILE_SIZE = dis.readLong();

 System.out.println(FILE_SIZE+"processing"); 

String FILE_NAME = dis.readUTF(); System.out.println(FILE_NAME+"processing");

 //String FILEHASH = dis.readUTF(); // System.out.println(FILEHASH+"processing"); 

File file = new File("c:\\aylo\\"+FILE_NAME); 

/** * what do We Have TO Say? */
 if(file.exists()){ 
long SIZE = file.length(); 
if(SIZE<FILE_SIZE){ 


String RESUME = "RESUME";   

//tell client to resume the upload
 dos.writeUTF(RESUME); 

/*sending the resuming length in*/ string String size = String.valueOf(SIZE);

 dos.writeUTF(size); 
dos.flush();

 fos=new FileOutputStream(file,true);
//append to exisiting file 

byte[] b = new byte [1024]; int COUNT_BYTES_READ ;
 while( (COUNT_BYTES_READ = dis.read(b)) >0){ 
fos.write(b);
 fos.flush();
} 
} 
} else{ 
} 
if(!file.exists()){
 file.getParentFile().mkdirs();
 file.createNewFile();

 String SEND = "SEND";
 dos.writeUTF(SEND);
 dos.flush();
 fos=new FileOutputStream(file); 

byte b[]=new byte[1024];

 int s;
 while((s=dis.read(b))>0){ 
fos.write(b,0,s); fos.flush(); System.out.println(s+"processing"); 
} 

} 
System.out.println("i'm done reading ");



}catch(Exception ex){ 

ex.printStackTrace();

 }finally{
 fos.close(); 
if(this.ss!=null) this.ss.close(); 
} 
}   

//the main

public static void main(String []arg){

     UserServer us = new UserServer("localhost", 2089);
     us.startserver();      

    //start client

 UploadManager.setup("localhost", 2089, ("c:\\movies\\hallow.mp4")); 
    }
     }

I've searched and searched most forums and OS about this and found nothing. What I'm trying to do is to learn or figure out how I can resume a file interrupted on upload through java socket. Right now my code partially works, but there's always a break or gap which I assumed is caused by the new FileOutputStream(from,true); constructor Can anyone pls check my methods and help point out my mistakes a sample code demo too will be nice. Thanks!

aloy
  • 53
  • 6

1 Answers1

2

Please review java convention on variable names; it took me quite a while to find your problem, and a lot of it is down to the fact that your code looks unfamiliar. Also, really, review your names. Naming a byte buffer to transfer bytes 'size' is similar to naming your favourite cat 'horse'. It's going to cause confusion.

The problem: You have quite a few places where you do this:

   byte[] buffer = new byte[8192];
   int bytesRead = networkIn.read(buffer);
   fileOut.write(buffer);

and this is incorrect. The 'write' call will write the entire buffer, all 8192 bytes, even if fewer than 8192 bytes were actually read. What you need to do is this:

   byte[] buffer = new byte[8192];
   int bytesRead = networkIn.read(buffer);
   fileOut.write(buffer, 0, bytesRead);

NB: It is possible there are more bugs in your code; the above is one that's definitely going to cause issues and would explain why a resume operation produces a corrupted file.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72