Retomar o upload / download de arquivo após a conexão perdida (programação de soquete)

Estou escrevendo um programa para baixar / carregar um arquivo entre um cliente e um servidor usando a programação de soquete. O código que escrevi até agora funciona no sentido de que posso transferir arquivos com êxito. No entanto, se uma conexão falhar devido a um problema na rede / cliente / servidor enquanto um download / upload estiver ocorrendo .. eu preciso RETOMAR o download / upload a partir do ponto original (não deseja que os dados enviados originalmente sejam reenviados). Não tenho certeza de como fazer isso. Estou lendo o arquivo em uma matriz de bytes e enviando-o pela rede. Minha idéia inicial é que sempre que estiver baixando .. devo verificar se o arquivo já existe e ler os dados em uma matriz de bytes -> enviar os dados ao servidor para comparação e depois reter, urn os dados restantes do servidor comparando as matrizes de dois bytes. Mas isso parece ineficiente e tira o ponto de retomar um download (já que estou enviando os dados novamente). Nota: O nome do arquivo é um identificador exclusivo. Eu realmente apreciaria se alguém pudesse me dar sugestões sobre como eu deveria implementar a funcionalidade de retomar o arquivo?

Server side code:
    package servers;
    import java.io.*;
    import java.net.*;
    import java.util.Arrays;
    public class tcpserver1 extends Thread
    {
        public static void main(String args[]) throws Exception 
    {
        ServerSocket welcomeSocket = null;
        try
        {
             welcomeSocket = new ServerSocket(5555);
             while(true)
             {
                 Socket socketConnection = welcomeSocket.accept();
                 System.out.println("Server passing off to thread");
                 tcprunnable tcprunthread = new tcprunnable(socketConnection);
                 Thread thrd = new Thread(tcprunthread);
                 thrd.start();
                 System.out.println(thrd.getName());
             }
        }
         catch(IOException e){
             welcomeSocket.close();
             System.out.println("Could not connect...");
         }
      }
}
class tcprunnable implements Runnable
{
    Socket socke;
    public tcprunnable(Socket sc){
         socke = sc;
    }


    public void download_server(String file_name)
    {   
        System.out.println("Inside server download method");
        try
        {
        System.out.println("Socket port:" + socke.getPort());

        //System.out.println("Inside download method of thread:clientsentence is:"+clientSentence);
        // Create & attach output stream to new socket
        OutputStream outToClient = socke.getOutputStream();
        // The file name needs to come from the client which will be put in here below
        File myfile = new File("D:\\ "+file_name);
        byte[] mybytearray = new byte[(int) myfile.length()];
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
        bis.read(mybytearray, 0, mybytearray.length);
        outToClient.write(mybytearray, 0, mybytearray.length);
        System.out.println("Arrays on server:"+Arrays.toString(mybytearray));
        outToClient.flush();
        bis.close();    
    }
        catch(FileNotFoundException f){f.printStackTrace();}
        catch(IOException ie){
            ie.printStackTrace();
        }
    }

    public void upload_server(String file_name){

        try{

        byte[] mybytearray = new byte[1024];
            InputStream is = socke.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            FileOutputStream fos = new FileOutputStream("D:\\ "+file_name);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            int bytesRead = is.read(mybytearray, 0, mybytearray.length);
                    bos.write(mybytearray, 0, bytesRead);
            do {
                baos.write(mybytearray);
                bytesRead = is.read(mybytearray);
        }
            while (bytesRead != -1);
            bos.write(baos.toByteArray());
            System.out.println("Array on server while downloading:"+Arrays.toString(baos.toByteArray()));
            bos.close();
    }
        catch(FileNotFoundException fe){fe.printStackTrace();}
        catch(IOException ie){ie.printStackTrace();}


    }

    @Override
    public void run()
    {   
        try
        {       
            System.out.println("Server1 up and running" + socke.getPort());
            //  Create & attach input stream to new socket
                BufferedReader inFromClient = new BufferedReader
                (new InputStreamReader(socke.getInputStream()));
                // Read from socket
                String  clientSentence = inFromClient.readLine();
                String file_name = inFromClient.readLine();

                System.out.println("Sever side filename:" + file_name);
                try{
                if(clientSentence.equals("download"))
                {
                    download_server(file_name);
                }
                else if(clientSentence.equals("upload"))
                {

                    upload_server(file_name);
                    System.out.println("Sever side filename:" + file_name);
                }
                else
                {
                    System.out.println("Invalid input");
                }
                }
                catch(NullPointerException npe){
                    System.out.println("Invalid input!");
                }
                    socke.close();  
        }
        catch(IOException e)
        {
            e.printStackTrace();
            System.out.println("Exception caught");
        }           
    }
}

Código do lado do cliente:

package clients;
import java.io.*;
import java.net.*;
import java.util.Arrays;
public class tcpclient1 
{   
        public static void main (String args[]) throws Exception
        {   
                // Create input stream to send sentence to server
                BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
                Socket clientSocket = null;
                while(true){
                System.out.println("Please enter the server you want to use");
                System.out.println("Enter 1 for Server 1 and 2 for Server2");
                String server_choice = inFromUser.readLine();

                if(server_choice.equals("1")){
                // Create client socket to connect to server
                // The server to use will be specified by the user
                 clientSocket = new Socket("localhost",5555);
                 break;
                }
                else if(server_choice.equals("2"))
                {
                    clientSocket = new Socket("localhost",5556);
                    break;
                }
                else
                {
                    System.out.println("Invalid entry");
                }
        }


                System.out.println("Please enter download for dowloading");
                System.out.println("Please enter upload for uploading");

            // sentence is what'll be received from input jsp   
                String sentence = inFromUser.readLine();

                if(sentence.equals("download"))
                {
                    download_client(clientSocket,sentence);
                }
                else if(sentence.equals("upload"))
                {
                    upload_client(clientSocket,sentence);
                }
                else
                {
                    System.out.println("Invalid input");
                }

            clientSocket.close();
        }

        public static void download_client(Socket clientSocket , String sentence)
        {
            try{
            // Create output stream attached to socket
            DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

            // Send line to server
            outToServer.writeBytes(sentence+'\n');
            BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter the name of file to download:");
            String file_to_download = inFromUser.readLine();


            if(searching(file_to_download))
            {

                // Read local file and send that to the server for comparison
            // DONT THINK THIS IS THE RIGHT WAY TO GO ABOUT THINGS SINCE IT BEATS THE PURPOSE OF RESUMING A DOWNLOAD/UPLOAD 

            }


            // Send filetodownload to server
            outToServer.writeBytes(file_to_download+'\n');
            byte[] mybytearray = new byte[1024];
            InputStream is = clientSocket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            FileOutputStream fos = new FileOutputStream("E:\\ "+file_to_download);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            int bytesRead = is.read(mybytearray, 0, mybytearray.length);
            bos.write(mybytearray, 0, bytesRead);
            do {
                baos.write(mybytearray);
                bytesRead = is.read(mybytearray);
            }
            while (bytesRead != -1);
            bos.write(baos.toByteArray());
            System.out.println("Array on client while downloading:"+Arrays.toString(baos.toByteArray()));
            bos.close();    
      }
            catch(FileNotFoundException fe){fe.printStackTrace();}
            catch(IOException ie){ie.printStackTrace();}

        }
        public static void upload_client(Socket clientSocket, String sentence)
        {
                try{
                    // Create output stream attached to socket
                DataOutputStream outToServer1 = new DataOutputStream(clientSocket.getOutputStream());
                    // Send line to server
                outToServer1.writeBytes(sentence+'\n');
                    System.out.println("In the client upload method");

                    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
                    System.out.println("Enter the name of file to upload:");
                    String file_to_upload = inFromUser.readLine();
                    //System.out.println("Cline side file name:"+file_to_upload);
                    outToServer1.writeBytes(file_to_upload+'\n');
                    System.out.println(file_to_upload);
                    OutputStream outtoserver = clientSocket.getOutputStream();

            File myfile = new File("E:\\ "+file_to_upload);
            byte[] mybytearray = new byte[(int) myfile.length()];
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myfile));
            bis.read(mybytearray, 0, mybytearray.length);
            outtoserver.write(mybytearray, 0, mybytearray.length);

            System.out.println("filename:"+file_to_upload+"Arrays on client while uploading:"+Arrays.toString(mybytearray));
            outtoserver.flush();
            bis.close();    
                }
                catch(FileNotFoundException fe){fe.printStackTrace();}
                catch(IOException ie){ie.printStackTrace();}
        }


        public static boolean searching(String file_name)
        {
            String file_path = "E:\\ "+file_name;
            File f = new File(file_path);
            if(f.exists() && !f.isDirectory()) { return true; }
            else
                return false;

        }       
       }

O código acima funciona bem para transferir arquivos entre o cliente e o servidor.
Mais uma vez, realmente aprecio qualquer ajuda!

questionAnswers(2)

yourAnswerToTheQuestion