Question

I'm trying to send my image from android client to Java server. Size of image that i'm sending is about 99kb, but server always reads a few kb less, sometimes 98, sometimes 96 and so on. I'd like to know why that data is lost and how can I send image in a proper way. Please help :)

Code:

Client(sending image):
    public void sendImage(File file){
        try {
            out = new PrintWriter(socket.getOutputStream(),true);
            out.println("Image");
            out.println(file.length());
            byte[] byteArray = new byte[(int) file.length()];
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            bis.read(byteArray,0,byteArray.length);
            OutputStream os = socket.getOutputStream();
            FilterOutputStream bos = new  FilterOutputStream(os);
            bos.write(byteArray,0,byteArray.length);
            bos.flush();
            os.close();
            bis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Server(receiving image):

if(input.equals("Image")){
                        input = in.readLine();
                        int fileSize = Integer.parseInt(input);
                        System.out.println("FILESIZE:" +fileSize);
                        byte[] byteArray = new byte[fileSize];
                        FileOutputStream fileOutputStream = 
                                new FileOutputStream("filename.jpg");
                        BufferedOutputStream bos = 
                                new BufferedOutputStream(fileOutputStream);
                        BufferedInputStream bis = new BufferedInputStream(in_);
                        int bytesRead = bis.read(byteArray, 0, byteArray.length);
                        int current = bytesRead;
                        do {
                                bytesRead = bis.read(byteArray, current,
                                                (byteArray.length - current));
                                if (bytesRead >= 0) {
                                    current += bytesRead;
                                    System.out.println(current);
                                }
                         } while (bytesRead != -1);
                        bos.write(byteArray, 0, current);
                        bos.flush();
                        bos.close();
}

EDIT Problem solved, working code is as follows:

Client side:

        public void sendImage(File file){
             try {
                    DataOutputStream out = new DataOutputStream(
                            socket.getOutputStream());
                    out.writeChar('I');
                    DataInputStream dis = new DataInputStream(new FileInputStream(file));
                    ByteArrayOutputStream ao = new ByteArrayOutputStream();
                    int read = 0;
                    byte[] buf = new byte[1024];
                    while ((read = dis.read(buf)) > -1) {
                        ao.write(buf, 0, read);
                    }

                    out.writeLong(ao.size());
                    out.write(ao.toByteArray());
                    out.flush();
                    out.close();
                    dis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }

Server side:

                if(input =='I'){
                    DataInputStream dis = new DataInputStream(clientSocket.getInputStream());
                    long length = dis.readLong();
                    File to = new File("filename.jpg");
                    DataOutputStream dos = new DataOutputStream(
                            new FileOutputStream(to));
                    byte[] buffer = new byte[1024];
                    int len, current = 0;
                    System.out.println(length);
                    while ( current != length) {
                        len = dis.read(buffer);
                        dos.write(buffer, 0, len);
                        current += len;
                        System.out.println(current);
                    }
                    dis.close();
                    dos.close();
                }
Était-ce utile?

La solution

From my personal experience PrintWriter and Buffers dont work well together.. As buffers trying to read data before you tell it to it can "steal" data that it should not do. For example if you use any kind of buffered reader to read the input on the server side that buffer will steal some parts at the "start" of the incomming image becuase it think's it's just another line. You could always try using DataInputStream and DataOutputStream instead..

Client:

public void sendImage(File file) {
    try {
        DataOutputStream out = new DataOutputStream(
                socket.getOutputStream());
        out.writeChar('I'); // as image,
        DataInputStream dis = new DataInputStream(new FileInputStream(file));
        ByteArrayOutputStream ao = new ByteArrayOutputStream();
        int read = 0;
        byte[] buf = new byte[1024];
        while ((read = dis.read(buf)) > -1) {
            ao.write(buf, 0, read);
        }
        out.writeLong(ao.size());
        out.write(ao.toByteArray());
        out.flush();
        out.close();
        dis.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Server:

// assuming folder structure exists.
public void readImage(Socket s, File to) throws IOException {

    DataInputStream dis = new DataInputStream(s.getInputStream());
    char c = dis.readChar();
    if (c == 'I') {
        long length = dis.readLong();
        DataOutputStream dos = new DataOutputStream(
                new FileOutputStream(to));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = dis.read(buffer)) != -1) {
            dos.write(buffer, 0, len);
        }
        dis.close();
        dos.close();
    }

}

Autres conseils

As a starting point, in the client side, you will also need a loop for reading the local image, because are you sure that...

bis.read(byteArray,0,byteArray.length);

... is really reading the whole image? So you will also need a loop as in the server side.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top