【问题标题】:Netty, java.io.StreamCorruptedException: Unsupported version: 0Netty,java.io.StreamCorruptedException:不支持的版本:0
【发布时间】:2012-07-18 13:49:18
【问题描述】:

你好,我正在开发一个使用 Netty 的服务器。目标是能够来回发送对象。所以我使用 ObjectDecoderInputStream 和 ObjectEncoderOutputStream 配置了服务器。

所以我有一个客户端也使用 Netty 与服务器通信。客户端运行良好。

每当我使用 Java 的套接字从服务器接收一个可序列化对象时。发生了一些奇怪的事情,我在下面遇到了一个异常:

java.io.StreamCorruptedException: Unsupported version: 0
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.readStreamHeader(CompactObjectInputStream.java:38)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.jboss.netty.handler.codec.serialization.CompactObjectInputStream.<init>(CompactObjectInputStream.java:30)
at org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream.readObject(ObjectDecoderInputStream.java:115)
at com.bvd.main.Client.readResponse(Client.java:139)
at com.bvd.main.Client.getFile(Client.java:80)
at com.bvd.main.Client.main(Client.java:163)

从客户端发送一个对象:

    public static void writeRequest(Message requestMsg,
        OutputStream outputStream) {
    byte[] bytes = null;
    ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
    try {
        ObjectEncoderOutputStream objectOutputStream = new ObjectEncoderOutputStream(
                byteOutputStream, 8192);
        objectOutputStream.writeObject(requestMsg);
        objectOutputStream.flush();
        bytes = byteOutputStream.toByteArray();
        byteOutputStream.close();
        objectOutputStream.close();
        outputStream.write(bytes);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

以及客户端收到对象的代码:

    public static Object readResponse(InputStream inputStream) {
    int count = 0;
    Object object = null;
    try {
        byte[] lenBuffer = new byte[4];
        while ((count = inputStream.read(lenBuffer)) < 4) {
        }
        System.out.println(ByteBuffer.wrap(lenBuffer).getInt());
        int infolen = ByteBuffer.wrap(lenBuffer).getInt();
        byte[] objBuffer = new byte[infolen];
        while ((count = inputStream.read(objBuffer)) < infolen) {
        }
        byte[] totalBuf = new byte[4 + infolen];
        System.arraycopy(lenBuffer, 0, totalBuf, 0, lenBuffer.length);
        System.arraycopy(objBuffer, 0, totalBuf, lenBuffer.length,
                objBuffer.length);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
                totalBuf);
        System.out.println(byteArrayInputStream.available());
        ObjectDecoderInputStream objectDecoderInputStream = new ObjectDecoderInputStream(
                new BufferedInputStream(byteArrayInputStream));
        object = objectDecoderInputStream.readObject();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return object;
}

更让我困惑的是,当我在2858(byte)的服务器上设置发送对象内容的长度(该对象携带部分文件已转换为byte[])时,上面的客户端运行良好;当我将长度更改为 2859 或更大时,上面会出现 StreamCorruptedException

ps:发送对象工作正常,服务器接收成功并正确解码,所有问题都是关于从服务器接收对象的问题。

对不起,我的英语很差,感谢任何帮助。谢谢。

【问题讨论】:

    标签: java netty


    【解决方案1】:

    如果您最终进行了多次读取调用,那么在您的两个读取循环中,您将获得虚假数据:

        while ((count = inputStream.read(lenBuffer)) < 4) {
        }
    
    
        while ((count = inputStream.read(objBuffer)) < infolen) {
        }
    

    每次调用 read 时,它都会写入 byte[] 的开头。因此,每次循环时,您都会覆盖缓冲区中的部分数据,而不是读取整个缓冲区的数据。您需要跟踪当前偏移量(基于您目前已读取的数据量)并将其传递给线程read() 调用。另外,你应该积累计数,而不是分配给它。

    【讨论】:

    • 抱歉这么晚才回复你。我犯了一个错误,可以阻止 read() 方法读取我想要的足够字节。我已经解决了这个问题,所以我写了一个方法来读取我需要的任意长度的字节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2018-02-15
    • 2013-11-10
    • 2012-08-22
    • 1970-01-01
    • 2018-09-11
    相关资源
    最近更新 更多