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 >> >> >> > >
