hakan eryargi a écrit :
hi,
It's not a problem on the server side. Your client *must* assume that the received message may be received in pieces. Even the first int can be received on 4 subsequent reads (not likely though).

You have to deal about fragmentation on both sides, btw. Read this : http://mina.apache.org/handling-packet-fragementation.html


my server uses MINA with a custom codec and my client uses blocking IO.
codec is very similar to ObjectSerializationCodec except it uses a regular
ObjectOutputStream.

below is the encoder:

@Override
public void encode(IoSession session, Object message, ProtocolEncoderOutput
out) throws Exception {

ByteArrayOutputStream bos = new ByteArrayOutputStream(4096);
ObjectOutputStream oout = new ObjectOutputStream(bos);
oout.writeObject(message);
oout.flush();
byte[] bytes = bos.toByteArray();

IoBuffer buffer = IoBuffer.allocate(bytes.length + 4);
buffer.putInt(bytes.length);
buffer.put(bytes);
buffer.flip();
out.write(buffer);

}

on client, i create a DataInputStream over socket's input stream and use the
following code to read messages:

public Message read() throws IOException, ClassNotFoundException {

dataIn.readInt(); // skip the data size
ObjectInputStream oin = new ObjectInputStream(new
BufferedInputStream(dataIn));
return (Message) oin.readObject();

}

this throws no exceptions, seems to run fine except it skips some messages.
i suspected it was because of BufferedInputStream placed in the middle  (it
may read more than required) so removed it but didnt help.

finally i tried to read *size* bytes into a byte array and create an
ObjectInputStream out of that and that solved the problem. the code is:

public Message read() throws IOException, ClassNotFoundException {

int size = dataIn.readInt(); // skip the data size
if (size <= 0)

throw new StreamCorruptedException("block size: " + size);

byte[] block = new byte[size];
int totalRead = 0;
while (totalRead < size) {

int read = dataIn.read(block, totalRead, size-totalRead);

if (read == -1)

throw new EOFException();

totalRead += read;

}
ObjectInputStream oin = new ObjectInputStream(new
ByteArrayInputStream(block));
return (Message) oin.readObject();

}

any ideas what's the problem in first approach ?

thanks,
r a f t


Reply via email to