Resume file upload/download after lost connection (Socket programming)

后端 未结 2 1765
时光取名叫无心
时光取名叫无心 2020-12-09 14:14

I\'m writing a program to download/upload a file between a client and server using socket programming. The code i\'ve written till now works in the sense that i can sucesful

2条回答
  •  有刺的猬
    2020-12-09 14:45

    There are many ways which you can do this, I suggest you to create a separate type of request to the server that accepts the file's name and file position which is the position where in the file where the connection failed.

    That's how you will get the file from the server in the client's side:

    int filePosition = 0;
    
    InputStream is = clientSocket.getInputStream();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    
    do {
        baos.write(mybytearray);
        bytesRead = is.read(mybytearray);
    
        if(bytesRead != -1)
            filePosition += bytesRead;
    }
    while (bytesRead != -1);
    

    Now if the connection got interrupted for some reason you can send a request again to the server with the same file name and the filePosition, and the server will send the file back like this:

    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.skip(filePosition) //Advance the stream to the desired location in the file
    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();    
    

    And in the client you can open the file stream and specify append = true in the constructor like this:

    FileOutputStream fos = new FileOutputStream("D:\\ "+file_name, true);
    

    This could be one way to do this, there are a lot more options. And I also suggest verify the files after the transfer using some hash function like MD5 for example, it creates unique stamp for a given input and it always outputs same result for the same input, which means, you can create the stamp from the same file both in the server and in the client and if the file is truly the same, it will generate the same stamp. Since the stamp's size is very small relative to the file it self and it is also fixed, it can be send between the client/server without much overhead.

    You can generate an MD5 hash with this code:

    MessageDigest md = MessageDigest.getInstance("MD5");
    try (InputStream is = Files.newInputStream(Paths.get("file.txt"))) {
      DigestInputStream dis = new DigestInputStream(is, md);
      /* Read stream to EOF as normal... */
    }
    byte[] digest = md.digest();
    

    (taken from: Getting a File's MD5 Checksum in Java)

提交回复
热议问题