0

I am just trying to send some files from a socket and i am able to send those files without any interruption: also whether the size file is small or large that does not matter it sends like a charm.

But the problem in my case that is arising is the file that i sent is being corrupted, i.e. it is not playing like audio or video. I have already gone through this but it did not helped.

The code that I am using is below.

Server Side:

File file = new File(
                Environment.getExternalStorageDirectory(),
                "testingFile.mp4");
        byte[] mybytearray = new byte[4096];
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        }
        BufferedInputStream bis = new BufferedInputStream(fis);
        DataInputStream dis = new DataInputStream(bis);
        OutputStream os;
        DataOutputStream dos = null;
        try {
            os = socket.getOutputStream();
            dos = new DataOutputStream(os);
            dos.writeUTF(file.getName());
            dos.writeLong(mybytearray.length);
            int read;
            while ((read = dis.read(mybytearray)) != -1) {
                dos.write(mybytearray, 0, read);
            }
            socket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (dos != null) {
                    dos.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

And the Client Side :

File file = new File(
                    Environment.getExternalStorageDirectory(),
                    "TEST SUCCESS.mp4");
            InputStream in = null;
            int bufferSize;

            try {
                bufferSize = socket.getReceiveBufferSize();
                in = socket.getInputStream();
                DataInputStream clientData = new DataInputStream(in);
                String fileName = clientData.readUTF();
                System.out.println(fileName);
                OutputStream output = new FileOutputStream(
                        file);
                byte[] buffer = new byte[bufferSize];
                int read;
                while ((read = clientData.read(buffer)) != -1) {
                    output.write(buffer, 0, read);
                }
                output.flush();
                socket.close();

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (in != null) {
                    in.close();
                }

            }

Thanks in advance.

user207421
  • 305,947
  • 44
  • 307
  • 483
Md Aman
  • 340
  • 3
  • 10
  • 1
    Could you please show us the results of a small file that exhibits corruption? Please show us the original file, then the corrupted file. Sorry; I was assuming these were text files, not mp4's. – NomadMaker Aug 24 '20 at 03:58
  • @NomadMaker i am sending mp4 files not text.. please help me to solve this – Md Aman Aug 24 '20 at 04:06
  • You are sending from one `Socket` to another. `ServerSocket` has nothing to do with it. – user207421 Aug 24 '20 at 04:31
  • You are sending your buffer size for some reason, with `dos.writeLong(mybytearray.length)`, but you are never reading it, so it is going into the file ahead of all the data. You don't need this. Remove and re-test. – user207421 Aug 24 '20 at 04:35
  • @MarquisofLorne so please give me some code suggestion so that i can solve this curruption – Md Aman Aug 24 '20 at 04:35
  • The word is 'corruption'. – user207421 Aug 24 '20 at 04:36
  • as you mentioned `dos.writeLong(mybytearray.length)` to delete so i am just going to delete it and re testing wait – Md Aman Aug 24 '20 at 04:37
  • thanks a lot i just deleted this code `dos.writeLong(mybytearray.length)` as you mentioned and it is working like a charm, again thanks a lot :) – Md Aman Aug 24 '20 at 04:40
  • If you got this code from [this question](https://stackoverflow.com/questions/17285846/large-file-transfer-over-java-socket/17286974#17286974) you should read the comments first. Or just use the code in my answer [here](https://stackoverflow.com/questions/10367698/java-multiple-file-transfer-over-socket). – user207421 Aug 24 '20 at 07:25

2 Answers2

1

So after the conversations in comments and as @MarquisofLorne told to delete the line that i have written in my server side code. i.e either delete this line from server side code:

dos.writeLong(mybytearray.length);

or write this below line code in client side code:

long sizeOfFile = clientData.readLong();

It solves the problem.

user207421
  • 305,947
  • 44
  • 307
  • 483
Md Aman
  • 340
  • 3
  • 10
-1

Server Side

Your code sends buffer length(4096), which is a bug.

It should send file length.

File file = new File( ... );
try {
    //dos.writeLong(mybytearray.length);
    dos.writeLong(file.length());

}

Client Side

Server sends two meta data

  • file name( F bytes, encoded by utf-8)
  • file length (8 bytes)

And then sends entire contents( N bytes)

But client code ignores file length(8bytes), just reads file name and contents N bytes

    in = socket.getInputStream();
    DataInputStream clientData = new DataInputStream(in);

    String fileName = clientData.readUTF(); // ok read F bytes
    
    // missing readLong(..) 8 bytes
    // long fileLen = clientData.readLong(); <= read file length before reading contents
    
    // read N bytes, but first 8 bytes are file length, which are written into file.
    int read;
    while ((read = clientData.read(buffer)) != -1) {
        output.write(buffer, 0, read);
    }

Don't rely on -1

Your codes keep relying on -1 in while loop

  while ((read = dis.read(mybytearray)) != -1) {
    dos.write(mybytearray, 0, read);
  }

  while ((read = clientData.read(buffer)) != -1) {
    output.write(buffer, 0, read);
  }

-1 means abnormal state.

Because server knows the exact size of a file and writes out the file, client should read the exact length of bytes from stream.

If server send 1234 bytes, when client read -1 from clientData.read(..), it fails to read contents from stream, not end of stream.

chmin.seo
  • 271
  • 4
  • 10
  • This is Java, not C. -1 does not 'mean abnormal state': it means end of stream. See the Javadoc. He does not need to send the file length. His now working code proves it. – user207421 Aug 24 '20 at 07:12
  • NB `(file.length)` does not compile. – user207421 Aug 24 '20 at 07:23
  • `file.length` to `file.length()` – chmin.seo Aug 24 '20 at 08:00
  • Great, one typo corrected, one major error comprising half your answer not corrected; and as you haven't suggested what he should actually *do* with the file length there is nothing here of value at all. – user207421 Aug 24 '20 at 08:10