A few pointers:
1)  All objects are instanceof Object, so you can rewrite "else if(message
instance of Object) { ... } " as "else { ... }"
2) You're trying to debug encoding and decoding at the same time, and any
time you see a failure, you don't know which side to fix. Instead write
some unit tests:
  - for encoding, encode to a byte[] (via a ByteArrayOutputStream, if you
want your method to use that) and assertEquals against a hand-crafted byte
array
  - for decoding, start with a hand-crafted byte array, decode (maybe via
ByteArrayOutputStream and assertEquals against the expected object.

When I say "hand-craft", you can computer-assist the creation. For example,
for one of your samples you can write a short program to just encode an
object, System.out.println(Arrays.toString(byteArray), copy/paste the
result into your unit test code, and add '@' at the front.

Get this all working separately to any networking concerns first. Then work
to address buffer fragmentation.

On Thu Feb 26 2015 at 08:56:06 Emmanuel Lécharny <[email protected]>
wrote:

> Le 26/02/15 08:16, Abeer Al-Anazi a écrit :
> > did you mean like this:
> > encode function:
> >     public void encode(IoSession session, Object message,
> > ProtocolEncoderOutput out) throws Exception {
> >     byte b;
> >         IoBuffer buffer = IoBuffer.allocate(1200, false);
> >        buffer.setAutoExpand(true);
> >         if (message instanceof Long )
> >         {    b = '@';
> >
> >              buffer.put (b);
> >              long controllerCurrentLoad= (Long) message;
> >              byte[] bytes3 = getBytes(controllerCurrentLoad);
> >              buffer.putInt(bytes3.length);
> >              buffer.put(bytes3);
> >
> >         }
> >         else if ( message instanceof HashMap )
> >         {    b = '#';
> >              HashMap <SocketAddress, Long> loadTable = new
> > HashMap<SocketAddress, Long> ();
> >               loadTable = (HashMap<SocketAddress, Long>) message;
> >                byte[] bytes1 = getBytes( loadTable);
> >                 buffer.put(b);
> >                 buffer.putInt(bytes1.length);
> >                 buffer.put(bytes1);
> >
> >         }
> >         else if ( message instanceof Object )
> >         {
> >             b = '&';
> >              buffer.put (b);
> >         controllerInfo  request = (controllerInfo ) message;
> >         byte[] bytes2 = getBytes(request);
> >         buffer.putInt(bytes2.length);
> >         buffer.put(bytes2);
> >         }
> >
> >
> >            buffer.flip();
> >            out.write(buffer);
> >     }
> > *********************************
> > public static byte[] getBytes(Object obj) throws IOException {
> >             ByteArrayOutputStream b = new ByteArrayOutputStream();
> >             ObjectOutputStream o = new ObjectOutputStream(b);
> >             o.writeObject(obj);
> >             return b.toByteArray();
> > *****************************************************************
>
>
> The encode function seems ok, IFAICT. I'm not sure that writing a char
> ('@' or '&') will not write 2 bytes instead of 1, which might be a pb
> when decoding, as you may perfectly receive 1 sinle byte first, then the
> remaining bytes. Cast it to a byte.
>
>
> > decode function:
> > rotected boolean doDecode(IoSession session, IoBuffer in,
> > ProtocolDecoderOutput out) throws Exception {
> >     byte b = 0 ;
> >     long    controllerCurrentLoad = 0;
> >     controllerInfo r = new controllerInfo();
> >     while (in.hasRemaining())
> >     {
> >         b = in.get();
> >
> >       if (b == '&')
> >       {
> >
> >           if(in.prefixedDataAvailable(4))
>
> You are not dealing with buffer fragmentation here.
>
> What will you do if you don't receive 4 bytes ?
>
>
>
> >           {
> >              r = (controllerInfo) deserialize(in);
> >
> >           }
> >     }
> >      if (b == '@')
> >        {
> >             if(in.prefixedDataAvailable(4))
> >           {
> >           controllerCurrentLoad = (Long) deserialize(in);
> >
> >           }
> >
> >        }
> >      if (b == '#')
> >      {
> >         if (in.prefixedDataAvailable(4))
> >         {
> >
> >         HashMap<SocketAddress, Long> l = (HashMap<SocketAddress, Long>)
> > in.getObject();
> >         l = (HashMap<SocketAddress, Long>) deserialize(in);
> >          loadTable = l;
> >         }
> >
> >      }
> >     }
> >     controllerInfo request =r;
> >     request.setControllerLoad(controllerCurrentLoad);
> >     request.setSwitchesLoad(loadTable);
> >     out.write(request);
> >         return false;
> >     }
> >
> > *********************************************
> > public static Object deserialize(IoBuffer in) throws IOException,
> > ClassNotFoundException {
> >         int length = in.getInt();
> >         byte[] bytes = new byte[length];
> >         in.get(bytes);
> >         ByteArrayInputStream b = new ByteArrayInputStream(bytes);
> >         ObjectInputStream o = new ObjectInputStream(b);
> >         return o.readObject();
> > **********************************************************
> > I tested it but it did not work, and the decoder did not read any things.
> > If I discard using getByte and deserialize function, the decoder read the
> > object only and when I print the renaming in buffer -after read object-
> the
> > result is zero. I mean the decoder read only one of the message cases
> > (object-long-hashmap) and discard others.
>
> Have you printed whet you sent ? Is this what you get on the decoder side ?
>
> Does both buffer contain the initial char, the length and everything
> that you expect to be a serialized object ?
> > I think the problem is in buffer size, because it cant read more than one
>
>
> ???
> > (if cases).
> > I need your help please, I spent a lot of my time to try solving it :(
> Sorry, I do what I can, but at some point, I can't write your
> application...
>
>
>

Reply via email to