简体   繁体   English

通过套接字将图像从android客户端发送到Java服务器时数据丢失

[英]Data loss while sending image over socket from android client to Java server

I'm trying to send my image from android client to Java server. 我正在尝试将图像从android客户端发送到Java服务器。 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. 我要发送的图像大小约为99kb,但是服务器读取的图像总少一些,有时是98,有时是96,依此类推。 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();
                }

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. 从我的个人经验来看,PrintWriter和Buffers不能很好地协同工作。由于在尝试将数据告诉缓冲区之前试图读取数据的缓冲区会“窃取”它不应该做的数据。 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.. 您始终可以尝试使用DataInputStream和DataOutputStream代替。

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();
    }

}

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. 因此,您还需要在服务器端进行循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM