You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by angel figueroa <an...@updatecom.com> on 2007/05/11 22:40:49 UTC
ProtocolCodecFilter for Binary Data
Which protocol Filter can be use for receiving Binary Data?
The first two byte is a binary number. I am using TextLineCodecFactory but i
thing it does not call the messageReceived.
Any Help would be appreciated?
Example
Associated Data - 70 bytes
000: 0044 4953 4F30 3036 3030 3030 3430 3038
.DISO00600004008
008: 3030 3832 3230 3030 3030 3030 3030 3030
0082200000000000
010: 3030 3034 3030 3030 3030 3030 3030 3030
0004000000000000
018: 3030 3035 3130 3230 3237 3433 3030 3030
0005102027430000
020: 3335 3030 3103 35001.
--
View this message in context: http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
Sent from the mina dev mailing list archive at Nabble.com.
Re: ProtocolCodecFilter for Binary Data
Posted by angel figueroa <an...@updatecom.com>.
Hi,
You are correct, the first two byte indicate the length of the message
and the last byte is a hex 03 is a delimiter. indicate en of message.
thanks for the information that you provided. What we can do, i will
implemented the rotocolDecoder/Encoder that you supply to me. When is
working i will send to you to incorporate on the Tutorial.
If you have the changes to obtain the source code, i would appreciated if
you send to me for testing. Also can you send the Tutorial in order to
understand better the concept of coder/decoder.
Regards,
Angel Figueroa
Maarten Bosteels-4 wrote:
>
> Hi Angel,
>
> You should not use the TextLineCodecFactory for reading binary data.
> From the example data, I assume your messages have header with a fixed
> length of 2 bytes
> which should be interpreted as the number of remaining bytes, right ?
>
> I have been working on a tutorial on writing your own
> ProtocolDecoder/Encoder, unfortunately I don't have the code right here.
> but I tried to reproduce it off the top of my head.
> I believe it does what you want, but I have not tested it :-)
>
> The decoder itself is stateless: it stores the conversational state in the
> IoSession.
> This means you can use the same decoder instance for all your sessions.
>
> import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> import org.apache.mina.common.IoSession;
> import org.apache.mina.common.ByteBuffer;
>
> public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder {
>
> private static class DecoderState {
> /** whether we have already read the fixed-length header */
> boolean headerRead = false;
> /** the length of the payload */
> int length;
> }
>
> /** the header has a fixed length of 2 bytes */
> private final static int HEADER_LENGTH = 2;
>
> private final static String DECODER_STATE_KEY =
> ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
>
> protected boolean doDecode(IoSession session, ByteBuffer in,
> ProtocolDecoderOutput out) throws Exception {
> DecoderState state = (DecoderState) session.getAttribute
> (DECODER_STATE_KEY);
> if (state == null) {
> state = new DecoderState();
> session.setAttribute(DECODER_STATE_KEY, state);
> }
> if (!state.headerRead) {
> // we have not yet read the header => check if have enough bytes to
> read the fixed-length header
> if (in.remaining() >= HEADER_LENGTH) {
> state.length = in.getShort();
> state.headerRead = true;
> } else {
> // not enough bytes to decode a message, MINA will call us again
> when there is more data available
> return false;
> }
> }
> if (state.headerRead) {
> // we have already read the lengt header, check if all the data is
> available
> if (in.remaining() >= state.length) {
> // ok, message complete
> byte[] bytes = new byte[state.length];
> in.get(bytes);
>
> // this will cause IoHandler.messageReceived() to be called with a
> byte[] as the message
> out.write(bytes);
>
> // remove the decoder state to be ready for the next message
> session.removeAttribute(DECODER_STATE_KEY);
> return true;
> }
> // not enough bytes available
> return false;
> }
> return false;
> }
> }
>
> Hope that helps,
> Maarten
>
> On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>>
>>
>> Which protocol Filter can be use for receiving Binary Data?
>> The first two byte is a binary number. I am using TextLineCodecFactory
>> but
>> i
>> thing it does not call the messageReceived.
>>
>> Any Help would be appreciated?
>>
>> Example
>> Associated Data - 70 bytes
>> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
>> .DISO00600004008
>> 008: 3030 3832 3230 3030 3030 3030 3030 3030
>> 0082200000000000
>> 010: 3030 3034 3030 3030 3030 3030 3030 3030
>> 0004000000000000
>> 018: 3030 3035 3130 3230 3237 3433 3030 3030
>> 0005102027430000
>> 020: 3335 3030 3103 35001.
>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
>> Sent from the mina dev mailing list archive at Nabble.com.
>>
>>
>
>
--
View this message in context: http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440066
Sent from the mina dev mailing list archive at Nabble.com.
Re: ProtocolCodecFilter for Binary Data
Posted by mat <fo...@gmail.com>.
What is the difference to use CumulativeProtocolDecoder than to use
DemuxingProtocolCodec?
2007/5/12, angel figueroa <an...@updatecom.com>:
>
>
> Hi,
>
> the example that you mention is for the decoder. But what about the
> Encoder.?
>
> Thanks in advance for all the information that you are providing.
>
> Regards,
> Angel Figueroa
>
>
> Maarten Bosteels-4 wrote:
> >
> > Hi Angel,
> >
> > You should not use the TextLineCodecFactory for reading binary data.
> > From the example data, I assume your messages have header with a fixed
> > length of 2 bytes
> > which should be interpreted as the number of remaining bytes, right ?
> >
> > I have been working on a tutorial on writing your own
> > ProtocolDecoder/Encoder, unfortunately I don't have the code right here.
> > but I tried to reproduce it off the top of my head.
> > I believe it does what you want, but I have not tested it :-)
> >
> > The decoder itself is stateless: it stores the conversational state in
> the
> > IoSession.
> > This means you can use the same decoder instance for all your sessions.
> >
> > import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> > import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> > import org.apache.mina.common.IoSession;
> > import org.apache.mina.common.ByteBuffer;
> >
> > public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder
> {
> >
> > private static class DecoderState {
> > /** whether we have already read the fixed-length header */
> > boolean headerRead = false;
> > /** the length of the payload */
> > int length;
> > }
> >
> > /** the header has a fixed length of 2 bytes */
> > private final static int HEADER_LENGTH = 2;
> >
> > private final static String DECODER_STATE_KEY =
> > ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
> >
> > protected boolean doDecode(IoSession session, ByteBuffer in,
> > ProtocolDecoderOutput out) throws Exception {
> > DecoderState state = (DecoderState) session.getAttribute
> > (DECODER_STATE_KEY);
> > if (state == null) {
> > state = new DecoderState();
> > session.setAttribute(DECODER_STATE_KEY, state);
> > }
> > if (!state.headerRead) {
> > // we have not yet read the header => check if have enough bytes
> to
> > read the fixed-length header
> > if (in.remaining() >= HEADER_LENGTH) {
> > state.length = in.getShort();
> > state.headerRead = true;
> > } else {
> > // not enough bytes to decode a message, MINA will call us again
> > when there is more data available
> > return false;
> > }
> > }
> > if (state.headerRead) {
> > // we have already read the lengt header, check if all the data is
> > available
> > if (in.remaining() >= state.length) {
> > // ok, message complete
> > byte[] bytes = new byte[state.length];
> > in.get(bytes);
> >
> > // this will cause IoHandler.messageReceived() to be called with
> a
> > byte[] as the message
> > out.write(bytes);
> >
> > // remove the decoder state to be ready for the next message
> > session.removeAttribute(DECODER_STATE_KEY);
> > return true;
> > }
> > // not enough bytes available
> > return false;
> > }
> > return false;
> > }
> > }
> >
> > Hope that helps,
> > Maarten
> >
> > On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
> >>
> >>
> >> Which protocol Filter can be use for receiving Binary Data?
> >> The first two byte is a binary number. I am using TextLineCodecFactory
> >> but
> >> i
> >> thing it does not call the messageReceived.
> >>
> >> Any Help would be appreciated?
> >>
> >> Example
> >> Associated Data - 70 bytes
> >> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
> >> .DISO00600004008
> >> 008: 3030 3832 3230 3030 3030 3030 3030 3030
> >> 0082200000000000
> >> 010: 3030 3034 3030 3030 3030 3030 3030 3030
> >> 0004000000000000
> >> 018: 3030 3035 3130 3230 3237 3433 3030 3030
> >> 0005102027430000
> >> 020: 3335 3030 3103 35001.
> >>
> >>
> >> --
> >> View this message in context:
> >>
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
> >> Sent from the mina dev mailing list archive at Nabble.com.
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440123
> Sent from the mina dev mailing list archive at Nabble.com.
>
>
Re: ProtocolCodecFilter for Binary Data
Posted by Maarten Bosteels <mb...@gmail.com>.
On 5/12/07, angel figueroa <an...@updatecom.com> wrote:
>
>
> I am working on it right known.
> Question who is responsible for the bytebuffer.
http://mina.apache.org/report/1.1/apidocs/org/apache/mina/common/ByteBuffer.html
The bytebuffer allocated by the encoder is passed to
ProtocolEncoderOutput.write(ByteBuffer)<http://mina.apache.org/report/1.1/apidocs/org/apache/mina/filter/codec/ProtocolEncoderOutput.html#write%28org.apache.mina.common.ByteBuffer%29>.so
MINA will release it for you.
Maarten
Regards,
> Angel Figueroa
>
>
>
> Maarten Bosteels-4 wrote:
> >
> > As usual, encoding is easier than decoding:
> >
> > import org.apache.mina.filter.codec.ProtocolEncoder;
> > import org.apache.mina.filter.codec.ProtocolEncoderOutput;
> > import org.apache.mina.common.IoSession;
> > import org.apache.mina.common.ByteBuffer;
> >
> > public class ByteArrayProtocolEncoder implements ProtocolEncoder {
> >
> > public void encode(IoSession session, Object message,
> > ProtocolEncoderOutput out) throws Exception {
> > byte[] bytes = (byte[]) message;
> > ByteBuffer buffer = ByteBuffer.allocate(bytes.length + 2);
> > // write the fixed length header
> > buffer.putShort((short)bytes.length);
> > // write the payload
> > buffer.put(bytes);
> > buffer.flip();
> > out.write(buffer);
> > }
> >
> > public void dispose(IoSession session) throws Exception {
> > // nothing to dispose
> > }
> > }
> >
> > Let me know if it works.
> >
> > Maarten
> >
> >
> > On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
> >>
> >>
> >> Hi,
> >>
> >> the example that you mention is for the decoder. But what about the
> >> Encoder.?
> >>
> >> Thanks in advance for all the information that you are providing.
> >>
> >> Regards,
> >> Angel Figueroa
> >>
> >>
> >> Maarten Bosteels-4 wrote:
> >> >
> >> > Hi Angel,
> >> >
> >> > You should not use the TextLineCodecFactory for reading binary data.
> >> > From the example data, I assume your messages have header with a
> fixed
> >> > length of 2 bytes
> >> > which should be interpreted as the number of remaining bytes, right ?
> >> >
> >> > I have been working on a tutorial on writing your own
> >> > ProtocolDecoder/Encoder, unfortunately I don't have the code right
> >> here.
> >> > but I tried to reproduce it off the top of my head.
> >> > I believe it does what you want, but I have not tested it :-)
> >> >
> >> > The decoder itself is stateless: it stores the conversational state
> in
> >> the
> >> > IoSession.
> >> > This means you can use the same decoder instance for all your
> sessions.
> >> >
> >> > import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> >> > import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> >> > import org.apache.mina.common.IoSession;
> >> > import org.apache.mina.common.ByteBuffer;
> >> >
> >> > public class ByteArrayProtocolDecoder extends
> CumulativeProtocolDecoder
> >> {
> >> >
> >> > private static class DecoderState {
> >> > /** whether we have already read the fixed-length header */
> >> > boolean headerRead = false;
> >> > /** the length of the payload */
> >> > int length;
> >> > }
> >> >
> >> > /** the header has a fixed length of 2 bytes */
> >> > private final static int HEADER_LENGTH = 2;
> >> >
> >> > private final static String DECODER_STATE_KEY =
> >> > ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
> >> >
> >> > protected boolean doDecode(IoSession session, ByteBuffer in,
> >> > ProtocolDecoderOutput out) throws Exception {
> >> > DecoderState state = (DecoderState) session.getAttribute
> >> > (DECODER_STATE_KEY);
> >> > if (state == null) {
> >> > state = new DecoderState();
> >> > session.setAttribute(DECODER_STATE_KEY, state);
> >> > }
> >> > if (!state.headerRead) {
> >> > // we have not yet read the header => check if have enough
> bytes
> >> to
> >> > read the fixed-length header
> >> > if (in.remaining() >= HEADER_LENGTH) {
> >> > state.length = in.getShort();
> >> > state.headerRead = true;
> >> > } else {
> >> > // not enough bytes to decode a message, MINA will call us
> >> again
> >> > when there is more data available
> >> > return false;
> >> > }
> >> > }
> >> > if (state.headerRead) {
> >> > // we have already read the lengt header, check if all the data
> >> is
> >> > available
> >> > if (in.remaining() >= state.length) {
> >> > // ok, message complete
> >> > byte[] bytes = new byte[state.length];
> >> > in.get(bytes);
> >> >
> >> > // this will cause IoHandler.messageReceived() to be called
> >> with
> >> a
> >> > byte[] as the message
> >> > out.write(bytes);
> >> >
> >> > // remove the decoder state to be ready for the next message
> >> > session.removeAttribute(DECODER_STATE_KEY);
> >> > return true;
> >> > }
> >> > // not enough bytes available
> >> > return false;
> >> > }
> >> > return false;
> >> > }
> >> > }
> >> >
> >> > Hope that helps,
> >> > Maarten
> >> >
> >> > On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
> >> >>
> >> >>
> >> >> Which protocol Filter can be use for receiving Binary Data?
> >> >> The first two byte is a binary number. I am using
> TextLineCodecFactory
> >> >> but
> >> >> i
> >> >> thing it does not call the messageReceived.
> >> >>
> >> >> Any Help would be appreciated?
> >> >>
> >> >> Example
> >> >> Associated Data - 70 bytes
> >> >> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
> >> >> .DISO00600004008
> >> >> 008: 3030 3832 3230 3030 3030 3030 3030 3030
> >> >> 0082200000000000
> >> >> 010: 3030 3034 3030 3030 3030 3030 3030 3030
> >> >> 0004000000000000
> >> >> 018: 3030 3035 3130 3230 3237 3433 3030 3030
> >> >> 0005102027430000
> >> >> 020: 3335 3030 3103 35001.
> >> >>
> >> >>
> >> >> --
> >> >> View this message in context:
> >> >>
> >>
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
> >> >> Sent from the mina dev mailing list archive at Nabble.com.
> >> >>
> >> >>
> >> >
> >> >
> >>
> >> --
> >> View this message in context:
> >>
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440123
> >> Sent from the mina dev mailing list archive at Nabble.com.
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10450043
> Sent from the mina dev mailing list archive at Nabble.com.
>
>
Re: ProtocolCodecFilter for Binary Data
Posted by angel figueroa <an...@updatecom.com>.
I am working on it right known.
Question who is responsible for the bytebuffer.
Regards,
Angel Figueroa
Maarten Bosteels-4 wrote:
>
> As usual, encoding is easier than decoding:
>
> import org.apache.mina.filter.codec.ProtocolEncoder;
> import org.apache.mina.filter.codec.ProtocolEncoderOutput;
> import org.apache.mina.common.IoSession;
> import org.apache.mina.common.ByteBuffer;
>
> public class ByteArrayProtocolEncoder implements ProtocolEncoder {
>
> public void encode(IoSession session, Object message,
> ProtocolEncoderOutput out) throws Exception {
> byte[] bytes = (byte[]) message;
> ByteBuffer buffer = ByteBuffer.allocate(bytes.length + 2);
> // write the fixed length header
> buffer.putShort((short)bytes.length);
> // write the payload
> buffer.put(bytes);
> buffer.flip();
> out.write(buffer);
> }
>
> public void dispose(IoSession session) throws Exception {
> // nothing to dispose
> }
> }
>
> Let me know if it works.
>
> Maarten
>
>
> On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>>
>>
>> Hi,
>>
>> the example that you mention is for the decoder. But what about the
>> Encoder.?
>>
>> Thanks in advance for all the information that you are providing.
>>
>> Regards,
>> Angel Figueroa
>>
>>
>> Maarten Bosteels-4 wrote:
>> >
>> > Hi Angel,
>> >
>> > You should not use the TextLineCodecFactory for reading binary data.
>> > From the example data, I assume your messages have header with a fixed
>> > length of 2 bytes
>> > which should be interpreted as the number of remaining bytes, right ?
>> >
>> > I have been working on a tutorial on writing your own
>> > ProtocolDecoder/Encoder, unfortunately I don't have the code right
>> here.
>> > but I tried to reproduce it off the top of my head.
>> > I believe it does what you want, but I have not tested it :-)
>> >
>> > The decoder itself is stateless: it stores the conversational state in
>> the
>> > IoSession.
>> > This means you can use the same decoder instance for all your sessions.
>> >
>> > import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
>> > import org.apache.mina.filter.codec.ProtocolDecoderOutput;
>> > import org.apache.mina.common.IoSession;
>> > import org.apache.mina.common.ByteBuffer;
>> >
>> > public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder
>> {
>> >
>> > private static class DecoderState {
>> > /** whether we have already read the fixed-length header */
>> > boolean headerRead = false;
>> > /** the length of the payload */
>> > int length;
>> > }
>> >
>> > /** the header has a fixed length of 2 bytes */
>> > private final static int HEADER_LENGTH = 2;
>> >
>> > private final static String DECODER_STATE_KEY =
>> > ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
>> >
>> > protected boolean doDecode(IoSession session, ByteBuffer in,
>> > ProtocolDecoderOutput out) throws Exception {
>> > DecoderState state = (DecoderState) session.getAttribute
>> > (DECODER_STATE_KEY);
>> > if (state == null) {
>> > state = new DecoderState();
>> > session.setAttribute(DECODER_STATE_KEY, state);
>> > }
>> > if (!state.headerRead) {
>> > // we have not yet read the header => check if have enough bytes
>> to
>> > read the fixed-length header
>> > if (in.remaining() >= HEADER_LENGTH) {
>> > state.length = in.getShort();
>> > state.headerRead = true;
>> > } else {
>> > // not enough bytes to decode a message, MINA will call us
>> again
>> > when there is more data available
>> > return false;
>> > }
>> > }
>> > if (state.headerRead) {
>> > // we have already read the lengt header, check if all the data
>> is
>> > available
>> > if (in.remaining() >= state.length) {
>> > // ok, message complete
>> > byte[] bytes = new byte[state.length];
>> > in.get(bytes);
>> >
>> > // this will cause IoHandler.messageReceived() to be called
>> with
>> a
>> > byte[] as the message
>> > out.write(bytes);
>> >
>> > // remove the decoder state to be ready for the next message
>> > session.removeAttribute(DECODER_STATE_KEY);
>> > return true;
>> > }
>> > // not enough bytes available
>> > return false;
>> > }
>> > return false;
>> > }
>> > }
>> >
>> > Hope that helps,
>> > Maarten
>> >
>> > On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>> >>
>> >>
>> >> Which protocol Filter can be use for receiving Binary Data?
>> >> The first two byte is a binary number. I am using TextLineCodecFactory
>> >> but
>> >> i
>> >> thing it does not call the messageReceived.
>> >>
>> >> Any Help would be appreciated?
>> >>
>> >> Example
>> >> Associated Data - 70 bytes
>> >> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
>> >> .DISO00600004008
>> >> 008: 3030 3832 3230 3030 3030 3030 3030 3030
>> >> 0082200000000000
>> >> 010: 3030 3034 3030 3030 3030 3030 3030 3030
>> >> 0004000000000000
>> >> 018: 3030 3035 3130 3230 3237 3433 3030 3030
>> >> 0005102027430000
>> >> 020: 3335 3030 3103 35001.
>> >>
>> >>
>> >> --
>> >> View this message in context:
>> >>
>> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
>> >> Sent from the mina dev mailing list archive at Nabble.com.
>> >>
>> >>
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440123
>> Sent from the mina dev mailing list archive at Nabble.com.
>>
>>
>
>
--
View this message in context: http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10450043
Sent from the mina dev mailing list archive at Nabble.com.
Re: ProtocolCodecFilter for Binary Data
Posted by Maarten Bosteels <mb...@gmail.com>.
As usual, encoding is easier than decoding:
import org.apache.mina.filter.codec.ProtocolEncoder;
import org.apache.mina.filter.codec.ProtocolEncoderOutput;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.ByteBuffer;
public class ByteArrayProtocolEncoder implements ProtocolEncoder {
public void encode(IoSession session, Object message,
ProtocolEncoderOutput out) throws Exception {
byte[] bytes = (byte[]) message;
ByteBuffer buffer = ByteBuffer.allocate(bytes.length + 2);
// write the fixed length header
buffer.putShort((short)bytes.length);
// write the payload
buffer.put(bytes);
buffer.flip();
out.write(buffer);
}
public void dispose(IoSession session) throws Exception {
// nothing to dispose
}
}
Let me know if it works.
Maarten
On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>
>
> Hi,
>
> the example that you mention is for the decoder. But what about the
> Encoder.?
>
> Thanks in advance for all the information that you are providing.
>
> Regards,
> Angel Figueroa
>
>
> Maarten Bosteels-4 wrote:
> >
> > Hi Angel,
> >
> > You should not use the TextLineCodecFactory for reading binary data.
> > From the example data, I assume your messages have header with a fixed
> > length of 2 bytes
> > which should be interpreted as the number of remaining bytes, right ?
> >
> > I have been working on a tutorial on writing your own
> > ProtocolDecoder/Encoder, unfortunately I don't have the code right here.
> > but I tried to reproduce it off the top of my head.
> > I believe it does what you want, but I have not tested it :-)
> >
> > The decoder itself is stateless: it stores the conversational state in
> the
> > IoSession.
> > This means you can use the same decoder instance for all your sessions.
> >
> > import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> > import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> > import org.apache.mina.common.IoSession;
> > import org.apache.mina.common.ByteBuffer;
> >
> > public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder
> {
> >
> > private static class DecoderState {
> > /** whether we have already read the fixed-length header */
> > boolean headerRead = false;
> > /** the length of the payload */
> > int length;
> > }
> >
> > /** the header has a fixed length of 2 bytes */
> > private final static int HEADER_LENGTH = 2;
> >
> > private final static String DECODER_STATE_KEY =
> > ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
> >
> > protected boolean doDecode(IoSession session, ByteBuffer in,
> > ProtocolDecoderOutput out) throws Exception {
> > DecoderState state = (DecoderState) session.getAttribute
> > (DECODER_STATE_KEY);
> > if (state == null) {
> > state = new DecoderState();
> > session.setAttribute(DECODER_STATE_KEY, state);
> > }
> > if (!state.headerRead) {
> > // we have not yet read the header => check if have enough bytes
> to
> > read the fixed-length header
> > if (in.remaining() >= HEADER_LENGTH) {
> > state.length = in.getShort();
> > state.headerRead = true;
> > } else {
> > // not enough bytes to decode a message, MINA will call us again
> > when there is more data available
> > return false;
> > }
> > }
> > if (state.headerRead) {
> > // we have already read the lengt header, check if all the data is
> > available
> > if (in.remaining() >= state.length) {
> > // ok, message complete
> > byte[] bytes = new byte[state.length];
> > in.get(bytes);
> >
> > // this will cause IoHandler.messageReceived() to be called with
> a
> > byte[] as the message
> > out.write(bytes);
> >
> > // remove the decoder state to be ready for the next message
> > session.removeAttribute(DECODER_STATE_KEY);
> > return true;
> > }
> > // not enough bytes available
> > return false;
> > }
> > return false;
> > }
> > }
> >
> > Hope that helps,
> > Maarten
> >
> > On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
> >>
> >>
> >> Which protocol Filter can be use for receiving Binary Data?
> >> The first two byte is a binary number. I am using TextLineCodecFactory
> >> but
> >> i
> >> thing it does not call the messageReceived.
> >>
> >> Any Help would be appreciated?
> >>
> >> Example
> >> Associated Data - 70 bytes
> >> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
> >> .DISO00600004008
> >> 008: 3030 3832 3230 3030 3030 3030 3030 3030
> >> 0082200000000000
> >> 010: 3030 3034 3030 3030 3030 3030 3030 3030
> >> 0004000000000000
> >> 018: 3030 3035 3130 3230 3237 3433 3030 3030
> >> 0005102027430000
> >> 020: 3335 3030 3103 35001.
> >>
> >>
> >> --
> >> View this message in context:
> >>
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
> >> Sent from the mina dev mailing list archive at Nabble.com.
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440123
> Sent from the mina dev mailing list archive at Nabble.com.
>
>
Re: ProtocolCodecFilter for Binary Data
Posted by angel figueroa <an...@updatecom.com>.
Hi,
the example that you mention is for the decoder. But what about the
Encoder.?
Thanks in advance for all the information that you are providing.
Regards,
Angel Figueroa
Maarten Bosteels-4 wrote:
>
> Hi Angel,
>
> You should not use the TextLineCodecFactory for reading binary data.
> From the example data, I assume your messages have header with a fixed
> length of 2 bytes
> which should be interpreted as the number of remaining bytes, right ?
>
> I have been working on a tutorial on writing your own
> ProtocolDecoder/Encoder, unfortunately I don't have the code right here.
> but I tried to reproduce it off the top of my head.
> I believe it does what you want, but I have not tested it :-)
>
> The decoder itself is stateless: it stores the conversational state in the
> IoSession.
> This means you can use the same decoder instance for all your sessions.
>
> import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
> import org.apache.mina.filter.codec.ProtocolDecoderOutput;
> import org.apache.mina.common.IoSession;
> import org.apache.mina.common.ByteBuffer;
>
> public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder {
>
> private static class DecoderState {
> /** whether we have already read the fixed-length header */
> boolean headerRead = false;
> /** the length of the payload */
> int length;
> }
>
> /** the header has a fixed length of 2 bytes */
> private final static int HEADER_LENGTH = 2;
>
> private final static String DECODER_STATE_KEY =
> ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
>
> protected boolean doDecode(IoSession session, ByteBuffer in,
> ProtocolDecoderOutput out) throws Exception {
> DecoderState state = (DecoderState) session.getAttribute
> (DECODER_STATE_KEY);
> if (state == null) {
> state = new DecoderState();
> session.setAttribute(DECODER_STATE_KEY, state);
> }
> if (!state.headerRead) {
> // we have not yet read the header => check if have enough bytes to
> read the fixed-length header
> if (in.remaining() >= HEADER_LENGTH) {
> state.length = in.getShort();
> state.headerRead = true;
> } else {
> // not enough bytes to decode a message, MINA will call us again
> when there is more data available
> return false;
> }
> }
> if (state.headerRead) {
> // we have already read the lengt header, check if all the data is
> available
> if (in.remaining() >= state.length) {
> // ok, message complete
> byte[] bytes = new byte[state.length];
> in.get(bytes);
>
> // this will cause IoHandler.messageReceived() to be called with a
> byte[] as the message
> out.write(bytes);
>
> // remove the decoder state to be ready for the next message
> session.removeAttribute(DECODER_STATE_KEY);
> return true;
> }
> // not enough bytes available
> return false;
> }
> return false;
> }
> }
>
> Hope that helps,
> Maarten
>
> On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>>
>>
>> Which protocol Filter can be use for receiving Binary Data?
>> The first two byte is a binary number. I am using TextLineCodecFactory
>> but
>> i
>> thing it does not call the messageReceived.
>>
>> Any Help would be appreciated?
>>
>> Example
>> Associated Data - 70 bytes
>> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
>> .DISO00600004008
>> 008: 3030 3832 3230 3030 3030 3030 3030 3030
>> 0082200000000000
>> 010: 3030 3034 3030 3030 3030 3030 3030 3030
>> 0004000000000000
>> 018: 3030 3035 3130 3230 3237 3433 3030 3030
>> 0005102027430000
>> 020: 3335 3030 3103 35001.
>>
>>
>> --
>> View this message in context:
>> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
>> Sent from the mina dev mailing list archive at Nabble.com.
>>
>>
>
>
--
View this message in context: http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10440123
Sent from the mina dev mailing list archive at Nabble.com.
Re: ProtocolCodecFilter for Binary Data
Posted by Maarten Bosteels <mb...@gmail.com>.
Hi Angel,
You should not use the TextLineCodecFactory for reading binary data.
>From the example data, I assume your messages have header with a fixed
length of 2 bytes
which should be interpreted as the number of remaining bytes, right ?
I have been working on a tutorial on writing your own
ProtocolDecoder/Encoder, unfortunately I don't have the code right here.
but I tried to reproduce it off the top of my head.
I believe it does what you want, but I have not tested it :-)
The decoder itself is stateless: it stores the conversational state in the
IoSession.
This means you can use the same decoder instance for all your sessions.
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.ByteBuffer;
public class ByteArrayProtocolDecoder extends CumulativeProtocolDecoder {
private static class DecoderState {
/** whether we have already read the fixed-length header */
boolean headerRead = false;
/** the length of the payload */
int length;
}
/** the header has a fixed length of 2 bytes */
private final static int HEADER_LENGTH = 2;
private final static String DECODER_STATE_KEY =
ByteArrayProtocolDecoder.class.getName() + ".DECODER_STATE";
protected boolean doDecode(IoSession session, ByteBuffer in,
ProtocolDecoderOutput out) throws Exception {
DecoderState state = (DecoderState) session.getAttribute
(DECODER_STATE_KEY);
if (state == null) {
state = new DecoderState();
session.setAttribute(DECODER_STATE_KEY, state);
}
if (!state.headerRead) {
// we have not yet read the header => check if have enough bytes to
read the fixed-length header
if (in.remaining() >= HEADER_LENGTH) {
state.length = in.getShort();
state.headerRead = true;
} else {
// not enough bytes to decode a message, MINA will call us again
when there is more data available
return false;
}
}
if (state.headerRead) {
// we have already read the lengt header, check if all the data is
available
if (in.remaining() >= state.length) {
// ok, message complete
byte[] bytes = new byte[state.length];
in.get(bytes);
// this will cause IoHandler.messageReceived() to be called with a
byte[] as the message
out.write(bytes);
// remove the decoder state to be ready for the next message
session.removeAttribute(DECODER_STATE_KEY);
return true;
}
// not enough bytes available
return false;
}
return false;
}
}
Hope that helps,
Maarten
On 5/11/07, angel figueroa <an...@updatecom.com> wrote:
>
>
> Which protocol Filter can be use for receiving Binary Data?
> The first two byte is a binary number. I am using TextLineCodecFactory but
> i
> thing it does not call the messageReceived.
>
> Any Help would be appreciated?
>
> Example
> Associated Data - 70 bytes
> 000: 0044 4953 4F30 3036 3030 3030 3430 3038
> .DISO00600004008
> 008: 3030 3832 3230 3030 3030 3030 3030 3030
> 0082200000000000
> 010: 3030 3034 3030 3030 3030 3030 3030 3030
> 0004000000000000
> 018: 3030 3035 3130 3230 3237 3433 3030 3030
> 0005102027430000
> 020: 3335 3030 3103 35001.
>
>
> --
> View this message in context:
> http://www.nabble.com/ProtocolCodecFilter-for-Binary-Data-tf3729533.html#a10439119
> Sent from the mina dev mailing list archive at Nabble.com.
>
>