获得bytearray的负长度值

时间:2014-03-03 12:56:41

标签: java android

soc = new Socket(ip, port1);
    while (true)
    {
        DataInputStream dis = new DataInputStream(soc.getInputStream());
        int len = dis.readInt();
        Log.d("===============" + len, "-------------------" + len);
        byte data[] = null;
        data = new byte[len];
        dis.readFully(data);

        Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, len);
        ImageView image = (ImageView) findViewById(R.id.imageView1);
        image.setImageBitmap(bmp);
    }

这是我的android代码,从服务器获取字节数组,它显示在Image.I得到字节数组长度的负值,所以app停止。以上代码在PC中正常工作。并且还告诉我我是否正在使用正确的方法在android中显示图像到屏幕。

Logcat字段:

03-03 12:50:27.941: E/AndroidRuntime(7283): FATAL EXCEPTION: Thread-205
03-03 12:50:27.941: E/AndroidRuntime(7283): java.lang.NegativeArraySizeException: -1393754107
03-03 12:50:27.941: E/AndroidRuntime(7283):     at com.example.vnc.Screen$1.run(Screen.java:47)
03-03 12:50:27.941: E/AndroidRuntime(7283):     at java.lang.Thread.run(Thread.java:856)

服务器端:

        while(continueLoop){

        try{
        BufferedImage image = robot.createScreenCapture(rectangle);


        byte[] imageInByte;

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(image,"jpg", baos);
        baos.flush();
        imageInByte = baos.toByteArray();
        baos.close();
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeInt(imageInByte.length);
        System.out.println(imageInByte.length);
        dos.write(imageInByte);
        Thread.sleep(1000);
        dos.flush();
        }
        catch(Exception e)
        {}
                   try{
            Thread.sleep(100);
        }catch(InterruptedException e){
            e.printStackTrace();
        }
    }

2 个答案:

答案 0 :(得分:1)

  

这是我的android代码,从服务器获取字节数组,它显示在Image.I得到字节数组长度的负值,所以app停止。

您的代码正在执行的是读取正在解释数组大小的int。有时它读取的价值是负面的...这是无稽之谈。

我怀疑真正的问题是您阅读数据的方式与您编写数据的方式不符。如果您向我们展示了编写代码(或其规范)的代码,我们将更有可能告诉您实际问题是什么,并推荐一个实际工作的解决方案。


<强>更新

我想我明白了。我认为这是由于DataOutputStream中的一些内部缓冲...以及每次循环时打开一个新DataOutputStream的事实。会发生什么:

  1. 循环一次,打开DataInputStream并从中读取。这会导致所有当前可用的字节被缓冲。
  2. 然后你读取大小和字节,将下一个“消息”的前几个字节留在缓冲区中。
  3. 但是下一次循环你打开另一个DataInputStream。这会丢弃未读字节,并使读取器从逻辑流中的错误位置读取“长度”;即图像中的一些随机点。机会是&gt; 50%,这将看起来像负值或大的正值...导致例外。
  4. 将此行移至循环之前:

     DataInputStream dis = new DataInputStream(soc.getInputStream());
    

    你可能也应该在服务器端做同样的事情,虽然你明确刷新dos这一事实应该可以节省你。

答案 1 :(得分:0)