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

时间:2014-05-13 18:49:35

标签: java android sockets networking

我试图将我的图像从Android客户端发送到Java服务器。我发送的图像大小约为99kb,但服务器总是读取少kb,有时98,有时96等等。我想知道数据丢失的原因以及如何以正确的方式发送图像。请帮助:)

代码:

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

服务器(接收图片):

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

修改 问题解决了,工作代码如下:

客户方:

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

服务器端:

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

2 个答案:

答案 0 :(得分:3)

根据我的个人经验,PrintWriter和Buffers不能很好地协同工作.. 在你告诉数据之前尝试读取数据的缓冲区可以“窃取”它不应该执行的数据。例如,如果您使用任何类型的缓冲读取器来读取服务器端的输入,那么缓冲区将在崩溃图像的“开始”处窃取某些部分,因为它认为它只是另一条线。您总是可以尝试使用DataInputStream和DataOutputStream ..

客户端:

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

服务器:

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

}

答案 1 :(得分:1)

作为起点,在客户端,您还需要一个循环来读取本地图像,因为您确定...

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

...真的在读整个图像吗?因此,您还需要在服务器端进行循环。