问题
I'm writing a java file-transfer app, and i have some troubles with deserialisation myself-defined class Message from Datagramms.
Other topics at StackOverflow has similar issues, but i didn't found something helpful from there, so i'm sorry in advance if i missed it.
so, class Message is:
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;
}
}
nothing special. i serialise it with
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();
}
and, actually, send it through datagram
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()));
I recieve it from other place by
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());
where (try/catch blocks are deleted here)
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;
}
why it can be? i did it according instructions at http://goo.gl/Rq1rMm
where and what i did wrong?
i checked that initial messages passes (i have them, but here is only a little piece of my code) and datagram in receive is not null. Moreover, sent and received datagrams has equal length.
Thanks in advance.
回答1:
receiveMSG = (Message) deserialize(receivedPacket.getData());
You need to change this to
receiveMSG = (Message) deserialize(receivedPacket.getData(), receivedPacket.getOffset(), receivedPacket.getLength);
and adjust your 'deserialise()' method accordingly, to accept 'offset' and 'length' parameters, and to use them when constructing the ByteArrayInputStream.
EDIT The code you posted doesn't compile: the expression that constructs the outgoing datagram packet is incorrect. It should be
new DatagramPacket(test, test.length, datagramSocket.getInetAddress(), datagramSocket.getPort())
I have no idea what packetOverhead
is supposed to be, but you don't need it.
NB You don't need to create a new Message()
the line before you call readObject().
回答2:
Are you sure you have received all of the bytes for the serialized objects? A DatagramSocket uses UDP under the hood. Are you sure that all of the packets have arrived?
Also, is it really a good idea to use UDP for transferring a serialized object? This is one case where TCP would seem to be more approriate. UDP does not guarantee delivery or delivery order which could easily cause a corrupted stream.
You should also really put a private static final long serialVersionUID = 1L;
on your Message class.
来源:https://stackoverflow.com/questions/23351748/deserialisation-issue-java-io-streamcorruptedexception-invalid-type-code-00