反序列化问题 - java.io.StreamCorruptedException:类型代码无效:00

时间:2014-04-28 21:48:30

标签: java serialization deserialization ioexception corruption

我正在编写一个java文件传输应用程序,我在使用数据报来自我定义的类消息时遇到了一些麻烦。

StackOverflow的其他主题有类似的问题,但我没有从那里找到有用的东西,所以如果我错过了,我很抱歉。

所以,类消息是:

import java.io.Serializable;

public class Message implements Serializable {

    private static final long serialVersionUID = 1L;

    private int segmentID;
    private byte[] packet;
    private int bytesToWrite;

    public Message(){
        segmentID = -1;
    }

    public Message(int segmentID, byte[] packet, int bytesToWrite) {
        this.segmentID = segmentID;
        this.packet = packet;
        this.bytesToWrite = bytesToWrite;
    }

    public int getBytesToWrite() {
        return bytesToWrite;
    }

    public int getSegmentID() {
        return segmentID;
    }

    public byte[] getPacket() {
        return packet;
    }
}
没什么特别的。 我用

序列化它
public byte[] serialize(Message obj) throws IOException
{
    ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
    ObjectOutputStream objectStream = new ObjectOutputStream(byteStream);
    objectStream.flush();
    objectStream.writeObject(obj);
    objectStream.flush();
    return byteStream.toByteArray();
}

实际上,通过数据报

发送
msg = new byte[512];
int bytesRead;
bytesRead = fileReader.read(msg);//fileReader is FileInputStream
Message message = new Message(segmentID, msg, bytesRead);
byte[] test = serialize(message);
datagramSocket.send(new DatagramPacket(test, test.length, 
    datagramSocket.getInetAddress(), datagramSocket.getPort()));

我通过

从其他地方接收到它
byte[] buffer = new byte[8192];
DatagramPacket receivedPacket = new DatagramPacket(buffer, buffer.length);
socket.recieve(recievedPacket); //it's already connected by init packet
receiveMSG = (Message) deserialize(receivedPacket.getData(), 
    receivedPacket.getOffset(), receivedPacket.getLength());

其中(此处删除了try / catch块)

private Object deserialize(byte[] bytes, int offset, int length)
{
    ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes, offset, length);
    ObjectInputStream objectStream = new ObjectInputStream(new BufferedInputStream(byteStream));
    Object tmpMsg = new Object();
        tmpMsg = objectStream.readObject();//here catches the EOFException
    return tmpMsg;
}

为什么会这样?我按照http://goo.gl/Rq1rMm的指示做了 哪里和我做错了什么? 我检查了初始消息通过(我有它们,但这里只是我的代码的一小部分)并且接收中的数据报不为空。而且,发送和接收的数据报具有相同的长度。 提前谢谢。

2 个答案:

答案 0 :(得分:1)

您确定已收到序列化对象的所有字节吗? DatagramSocket使用UDP。你确定所有数据包都已到达吗?

另外,使用UDP传输序列化对象真的是个好主意吗?这是TCP似乎更加合理的一种情况。 UDP不保证交付或交付订单,这可能很容易导致流损坏。

您还应该在Message类上添加private static final long serialVersionUID = 1L;

答案 1 :(得分:1)

  

receiveMSG =(Message)deserialize(receivedPacket.getData());

您需要将其更改为

receiveMSG = (Message) deserialize(receivedPacket.getData(), receivedPacket.getOffset(), receivedPacket.getLength);

并调整您的反序列()'相应的方法,接受“抵消”#39;和'长度'参数,并在构造ByteArrayInputStream时使用它们。

编辑您发布的代码无法编译:构造传出数据报包的表达式不正确。它应该是

new DatagramPacket(test, test.length, datagramSocket.getInetAddress(), datagramSocket.getPort())

我不知道packetOverhead应该是什么,但你不需要它。

注意:在致电new Message()之前,您不需要创建readObject().