0

sending side- It is in android and it is part of AsyncTask, doInBackground. Basically, it will send file name, size, and image data to serverside.

                InetAddress serverIP = InetAddress.getByName(IP);
                Socket client = new Socket(serverIP,SERVER_PORT);
                System.out.println("Connected to Server\n");
                System.out.println(imgFile.length());
                //sending name of the file
                PrintWriter name = new PrintWriter(new OutputStreamWriter(client.getOutputStream()),true);
                name.println(fileName);
                name.flush();
                //sending size of the file
                name.println(imgFile.length());
                name.flush();

                //sending body
                DataInputStream imgBodyIn = new DataInputStream(new FileInputStream(imgFile));
                DataOutputStream imgBodyOut = new DataOutputStream(client.getOutputStream());
                byte[] buffer = new byte[BUFFER_SIZE];
                int len;
                long filesize = imgFile.length();
                while(filesize >=0&& (len=imgBodyIn.read(buffer,0,(int)Math.min(buffer.length,filesize)))>0){
                    imgBodyOut.write(buffer,0,len);
                    filesize-=len;
                }
                name.close();
                imgBodyIn.close();
                imgBodyOut.flush();
                imgBodyOut.close(); 
                client.close();

Receiving side

          //receiving name
          BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream()));             
          String name = in.readLine();
          System.out.println("Name of the File : " + name+".JPG");
          //receiveing size info
          String size = in.readLine();
          System.out.println("Size of the File :"+size +"bytes");

          //storing file
          File f = new File("/home/ubuntu", name+".JPG");
          FileOutputStream output = new FileOutputStream(f);

          int len=0;
          long received=0;
          byte[] buf = new byte[BUFFER];
        while(received<=Long.parseLong(size)&&(len=sock.getInputStream().read(buf))>0)
         {  

            output.write(buf,0,len);
            received +=len;
            System.out.print("Receiving.."+received +"/"+size+"\r");


         }    
         output.flush();
         output.close();
         in.close();
         System.out.println("\n"+name+".JPG received");
         System.out.println("Size received :"+f.length()+"bytes");

when I tried to send a file, correct size info and name are transferred. However, I could not receive full file; some bytes are missing. Buffer size I am using is 1024.

Sample run :

 Waiting for client to connect..
Client Accepted

Name of the File : P1011474.JPG
Size of the File :714438bytes
Receiving..712997/714438
P1011474.JPG received
Size received :712997bytes

socket closed

1 Answer 1

0

Most likely it's the BufferedReader on the receiving side, which contains an internal buffer to improve performance when reading from the stream. See Javadoc:

Reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.

So it won't just read the two lines, but might as well read ahead after your two lines. Therefore a part of the binary image you appended might be buffered as well. When you then try to read the binary data directly from the InputStream wrapped with DataInputStream, you won't receive the bytes which were already buffered in the BufferedReader instance.

I would suggest, that you don't use a PrintWriter but instead write the file name and length directly using methods from DataOutputStream, e.g.:

out.writeUTF(fileName);
out.writeLong(imgFile.length());

On the receiving side use the read* methods of DataInputStream, instead of the BufferedReader. If you want to buffer, wrap the socket InputStream in a BufferedInputStream:

 DataInputStream dis = new DataInputStream(
     new BufferedInputStream(socket.getInputStream()));
 String fileName = dis.readUTF();
 long fileLength = dis.readLong();
 // now read file contents from stream

And by the way, you don't have to do:

imgBodyIn.read(buffer,0,(int)Math.min(buffer.length,filesize))

when reading in the image from a file, just do:

 imgBodyIn.read(buffer, 0, buffer.length)

The end of stream/file is recognized and read() will return the length of bytes read, so you don't need to do Math.min().

5
  • I am sorry but could you explain in detail ? Thank you. Commented Jul 3, 2013 at 4:38
  • @user2543738: I improved the explanation, if you have concrete questions, please ask.
    – nif
    Commented Jul 3, 2013 at 11:33
  • Thank you for clear explanation, I did change to above method both sender and receiver side but still receiving same amount(showed in thread). Commented Jul 3, 2013 at 14:08
  • I checked and the front part of image part is somewhat different from original. Commented Jul 3, 2013 at 14:12
  • Solved! by removing BufferedInputStream! Thank you! Commented Jul 3, 2013 at 19:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.