【问题标题】:send images via sockets without corrupting it通过套接字发送图像而不破坏它
【发布时间】:2020-01-18 19:05:23
【问题描述】:

大家好,我正在尝试编写一个 android 应用程序,用于通过套接字在 pc 上发送图像。 我有一个 android 客户端和一个 Java SE 服务器。 有时图像到达损坏,我不知道为什么。 我尝试发送 175 张照片,其中 9 张已损坏。 这是android客户端的代码: PS:我使用 ObjectInputStream 和 ObjectInputstream。

            try {

                //Get image
                //the variable "uri" is the uri of image
                InputStream is =  contentResolver.openInputStream(uri);
                final Bitmap bitmap = BitmapFactory.decodeStream(is);

                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
                byte array[] = baos.toByteArray();
                int length = array.length;
                Log.d("MY-DEBUG", "length: " + length);

                //Send lenght of image
                out.writeInt(length);
                out.flush();

                int remainent = length;
                int send = 0;
                int size = SIZE;

                while (remainent > 0) {
                    if (remainent < size)
                        size = remainent;

                    //System.out.println("ATTUALE: " + send + ", GRANDEZZA ARRAY: " + size);
                    out.write(array, send, size);
                    int percentage = (100 * send) / length;
                    publishProgress(percentage);
                    System.out.println("\n === FINE === \n");

                    send += size;
                    remainent -= size;
                    Log.d("MY-DEBUG", "Send " + send + "/" + length + " - remainent: " + remainent);
                }

                out.flush();

                Log.d("MY-DEBUG", "Immagine inviata");
                publishProgress(0);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

这是 Java SE 中的服务器代码

try {           
        //Read length
        int length = (int) in.readInt();

        File target = new File(percorso + "\\img-" + sequenza + ".jpg");
        outs = new FileOutputStream(target, true);
        System.out.println("Grandezza: " + length);
        int remainent = length;
        int read = 0;
        int total = 0;
        int size = SIZE;

        byte buffer[] = new byte[size];

        while ((read = in.read(buffer, 0, size)) != -1) {                           
            total += read;
            remainent = length - total;
            System.out.println("read: " + read + " - Received: " + total + "/" + length + " - remainent: " + remainent);
            int percentuale = (100 * total) / length;
            progressBar.setValue(percentuale);
            outs.write(buffer);
            outs.flush();

            Thread.sleep(1);
            if (remainent == 0) break;
        }

        progressBar.setValue(0);

        //Thread.sleep(100);

        //in.read();

        System.out.println("END");
    } catch (IOException e1) {
        System.err.println(e1.getMessage());
        e1.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        if (outs != null) {
            try {
                outs.flush();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    outs.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }
        Thread.currentThread().interrupt();
    }

SIZE 变量是这样声明的

private static final int SIZE = 1024;

如果我将值设置为 > 1024,所有照片到达时都已损坏。 如果我使用 1024,一些照片到达时已损坏。 非常感谢

【问题讨论】:

  • 也许您发送了额外的null 字节,要调试设置private static final int SIZE = 1; 并检查,是否有任何图像损坏?
  • tried to send 175 photos 。文件?那你为什么要转换为位图?按原样发送文件。
  • 是的,它适用于private static final int SIZE = 1; 我在位图中转换文件,因为 Android 10 给了我文件的 Uri,所以我从这个 Uri 获取位图文件
  • 所以?您还可以从 URL 中获取 bytes。直接。

标签: java android sockets jpeg


【解决方案1】:

问题是这一行:

outs.write(buffer);

您将无条件地写出整个缓冲区,该缓冲区始终为SIZE 字节长。但是如果你有一个“短”阅读呢?试试这个吧:

outs.write(buffer,0,read);

【讨论】:

  • 太棒了!现在工作正常! 175上的175张照片已经正确到达,非常感谢。您推荐的缓冲区大小是多少?我对 4096 的缓冲区进行了一些测试,但它似乎并不比 1024 快
  • @mamo 不客气,别忘了接受这个答案 :) 通常我喜欢 4096 左右的缓冲区大小用于套接字工作,但速度差异会非常非常小。此外,sleep() 调用的延迟往往会主导其他影响。
  • “睡眠”调用是出于测试目的,我已将其删除并设置了 4096 的缓冲区,但看起来相同。不过这并不重要,再次感谢!
猜你喜欢
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
相关资源
最近更新 更多