Hey Basil,
why not just using in.prefixedDataAvailable(4) in order to determine if
you have received the full length of your expected message or not.
Also, I think it's easier first to save the length, and THEN the type of
the message... and processed accordingly when decoding your messages.
Cu on the 'net,
Bye - bye,
<<<<< André <<<< >>>> èrbnA >>>>>
Basil Gasser wrote:
I'm not quite sure if I understand you correctly. What you are
saying is, that I should not use
int length = in.getInt(2) but length = in.getInt(in.markValue()+2);
or similar?
Below you will find the entire doDecode method. The decoder has to
determine the length of the message which is held in byte 3 to 6. From
this, we can determine if we have received the entire message (and
decode it) or not. If we were able to decode the message, we check if
there is already another message in the buffer, if so, return true,
false otherwise.
is there anything wrong with this approach? If I should not read
absolute values, what are the get...(int ) methods for?
thanks , Basil
Code:
protected boolean doDecode(IoSession session, IoBuffer in,
ProtocolDecoderOutput out) throws Exception {
// if 6 bytes in the buffer we can determine the next length to
see
// if buffer contains a completely delivered message.
int length = -1;
try {
length = in.getInt(2);
} catch (BufferUnderflowException e) {
// not enough bytes to determin length
log.debug("not enough bytes to determine message length");
return false;
}
if (in.remaining() >= length) {
// all bytes received to decode message
byte[] msg = new byte[length];
for (int i = 0; i < length; i++) {
msg[i] = (byte) in.get();
}
log.debug("message completely received");
log.debug("start decoding message");
LLRPMessage message =
LLRPMessageFactory.createLLRPMessage(msg);
log.debug("message decoded: " + message.getClass());
out.write(message);
// there might be an other message to be decoded
// see if there's another completly delivered message in
the buffer
// in this case, we would have to return true
try {
int prevLength = length;
length = in.getInt(prevLength + 2);
if (in.remaining() - in.markValue() >= length) {
log.debug("another message already in the buffer");
return true;
} else {
log.debug("message not yet completly delivered");
return false;
}
} catch (Exception e) {
// not enough bytes to determin length
log.debug("not enough bytes to determine message length");
return false;
}
}
return false;
}
"이희승 (Trustin Lee) <[EMAIL PROTECTED]>" wrote:
You should never assume that the received buffer's position is 0. Also,
please make sure you return true or false properly depending on the
number of bytes available in the received buffer, because packets can be
fragemented or assembled.
HTH,
Basil Gasser wrote:
I'm using Mina 2.0, the following code is taken from my
doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out )
method in my decoder which extends CumulativeProtocolDecoder
Concerning my protocol, a message contains its type in the second byte
(position 1 in an array)
// length is stored in byte 3 to 6
int length = in.getInt(2);
byte[] foo = in.array();
for (int u = 0; u<foo.length;u++){
System.out.print(foo[u]+" ");
}
System.out.println();
// all bytes received to decode message
byte[] msg = new byte[length];
int readtype = 0;
// read type of message
int designatedtype = in.get(1);
System.out.println("designated type: "+designatedtype);
for (int i = 0; i < length; i++) {
byte b = in.get();
System.out.print(b+ " ");
if (i ==1){
// type is second byte in a message
readtype = b;
}
msg[i] = (byte) b;
}
System.out.println();
System.out.println("read type: "+readtype);
byte[] current = in.array().clone();
for (int u = 0; u<current.length;u++){
System.out.print(current[u]+" ");
}
System.out.println();
This code is working perfectly fine in usual cases. However, when I
start my application in Eclipse, let it run for a while (it is
exchanging messages perfectly) stop it (I interrupt the execution) and
then let it run again, I get the following output:
4 61 0 0 0 10 0 0 9 19 4 31 0 0 0 18 ...
designated type: 61
1 31 0 8 0 0 0 0 4 30
read type: 31
4 61 0 0 0 10 0 0 9 19 4 31 0 0 0 18 ...
Obviously, the expected type is 61. But reading the buffer gives 31. It
seems that Buffer and underlying array are not in sync as reading twice
from the buffer gives 31 for the second byte.
Is this a bug in the Mina implementation? Am I doing something wrong
decoding the message (the system out statements would of course
normally
not be there. So I would call in.get() length times.)?
thanks.
++ Basil