ok but DataInputStream.readInt(), ObjectInputStream.readObject() and similar
methods take care of that, right ? they block until necessary amount of data
is available in the underlying stream. that's why i
used DataInputStream.readInt() to skip size block instead of read(new
byte[4]).

the thing here is, DataInputStream or ObjectInputStream somehow skips a *full
*block in stream. it's a full block othrwise we would get a StreamCorrupted
or similar exceptions..

On Sun, Jan 10, 2010 at 8:46 PM, Emmanuel LŽcharny <[email protected]>wrote:

> 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