You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by alimli <ha...@gmail.com> on 2007/07/25 17:26:07 UTC

TextLineDecoder decode function

Hi,
First, I want to mention that I'm new to Java. So I'm asking some silly
question don't blame me. :)

I wrote a subclass of TextLineDecoder and override decode function. Code
looks like below

public class CaiRequestDecoder extends  TextLineDecoder {
    
    private CharsetDecoder _decoder = Charset.forName("ASCII").newDecoder();
    
    /** Creates a new instance of CaiRequestDecoder */
    public CaiRequestDecoder() {
        super(Charset.forName("ASCII"), LineDelimiter.MAC);
    }
    
    public void decode(IoSession session, ByteBuffer in,
            ProtocolDecoderOutput out) throws Exception {
        // Try to decode body
        try {            
            CaiRequestMessage m = decodeBody(in);
            out.write(m);
        } catch(ProtocolDecoderException ex) {
//            session.write("RESP-1").join();
//            session.close();
        }
    }
    
    private CaiRequestMessage decodeBody(ByteBuffer in) throws 
ProtocolDecoderException  {
        String inStr = "";
        try {
            inStr = in.getString(_decoder);
            System.out.println("Buffer String :" + inStr);
            CaiRequestMessage request = parseRequest(new
StringReader(inStr));
            return request;
        } catch (CharacterCodingException ex) {
            ex.printStackTrace();
            return null;
        } 
    }

When I telnet my application for testing from a Solaris machine, I type the
input and press enter. Then my decode function is called. All is fine.

But when I try to telnet from windows and type sth. Every key triggers my
decode function. And HeapBuffer's limit is always 1. Only the last character
is returned from in.getString();

Is it sth. wrong with my code? I expect TextLineDecoder will only call
decode when a line is completed? Isn't this the default behaviour?

Thanks.
-- 
View this message in context: http://www.nabble.com/TextLineDecoder-decode-function-tf4142835s16868.html#a11784785
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: TextLineDecoder decode function

Posted by Kevin Smeltzer <ka...@lakeheadu.ca>.
I've seen this on Windows telnet as well. It seems to send characters
as soon as you type them without waiting for you to press ENTER. But I
obviously know nothing about the technical answer to that question :-D

On 7/25/07, alimli <ha...@gmail.com> wrote:
>
> Hi,
> First, I want to mention that I'm new to Java. So I'm asking some silly
> question don't blame me. :)
>
> I wrote a subclass of TextLineDecoder and override decode function. Code
> looks like below
>
> public class CaiRequestDecoder extends  TextLineDecoder {
>
>    private CharsetDecoder _decoder = Charset.forName("ASCII").newDecoder();
>
>    /** Creates a new instance of CaiRequestDecoder */
>    public CaiRequestDecoder() {
>        super(Charset.forName("ASCII"), LineDelimiter.MAC);
>    }
>
>    public void decode(IoSession session, ByteBuffer in,
>            ProtocolDecoderOutput out) throws Exception {
>        // Try to decode body
>        try {
>            CaiRequestMessage m = decodeBody(in);
>            out.write(m);
>        } catch(ProtocolDecoderException ex) {
> //            session.write("RESP-1").join();
> //            session.close();
>        }
>    }
>
>    private CaiRequestMessage decodeBody(ByteBuffer in) throws
> ProtocolDecoderException  {
>        String inStr = "";
>        try {
>            inStr = in.getString(_decoder);
>            System.out.println("Buffer String :" + inStr);
>            CaiRequestMessage request = parseRequest(new
> StringReader(inStr));
>            return request;
>        } catch (CharacterCodingException ex) {
>            ex.printStackTrace();
>            return null;
>        }
>    }
>
> When I telnet my application for testing from a Solaris machine, I type the
> input and press enter. Then my decode function is called. All is fine.
>
> But when I try to telnet from windows and type sth. Every key triggers my
> decode function. And HeapBuffer's limit is always 1. Only the last character
> is returned from in.getString();
>
> Is it sth. wrong with my code? I expect TextLineDecoder will only call
> decode when a line is completed? Isn't this the default behaviour?
>
> Thanks.
> --
> View this message in context: http://www.nabble.com/TextLineDecoder-decode-function-tf4142835s16868.html#a11784785
> Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.
>
>

Re: TextLineDecoder decode function

Posted by Trustin Lee <tr...@gmail.com>.
On 7/26/07, alimli <ha...@gmail.com> wrote:
> Trustin Lee wrote:
> >
> > You are using TextLineDecoder in a wrong way.  I'd suggest the
> > following implementation:
> >
> > 1) Use TextLineDecoder as it is; do not extend it.
> > 2) Once you inserted your protocol codec filter, your IoHandler's
> > messageReceived() will be provided with a line of string.
>
> Thanks for your reply, Trustin. I change my implementation according to your
> advice.
> But again, default TextLineCodecFactory does not work well with windows.
> Messages sent to client are only terminated with 0A character.

Default TextLineCodecFactory uses a TextLineDecoder with
LineDelimiter.UNIX.  I guess Windows telnet client doesn't understand
UNIX line delimiter.  I'd suggest you to try PuTTY.

> To fix this linedelimeter problem, I wrote a new codec factory with
>
>        encoder = new TextLineEncoder(Charset.forName("UTF-8"),
> LineDelimiter.WINDOWS);
>        decoder = new TextLineDecoder(Charset.forName("UTF-8"),
> LineDelimiter.WINDOWS);
>
> Interestingly, this works fine both from windows telnet and solaris telnet.

Right.  Most UNIX systems understand windows line delimiter.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP Key ID: 0x0255ECA6

Re: TextLineDecoder decode function

Posted by alimli <ha...@gmail.com>.

Trustin Lee wrote:
> 
> You are using TextLineDecoder in a wrong way.  I'd suggest the
> following implementation:
> 
> 1) Use TextLineDecoder as it is; do not extend it.
> 2) Once you inserted your protocol codec filter, your IoHandler's
> messageReceived() will be provided with a line of string.
> 
> HTH,
> Trustin
> -- 
> what we call human nature is actually human habit
> --
> http://gleamynode.net/
> --
> PGP Key ID: 0x0255ECA6
> 
> 

Thanks for your reply, Trustin. I change my implementation according to your
advice. 
But again, default TextLineCodecFactory does not work well with windows.
Messages sent to client are only terminated with 0A character. 

To fix this linedelimeter problem, I wrote a new codec factory with

        encoder = new TextLineEncoder(Charset.forName("UTF-8"),
LineDelimiter.WINDOWS);
        decoder = new TextLineDecoder(Charset.forName("UTF-8"),
LineDelimiter.WINDOWS);

Interestingly, this works fine both from windows telnet and solaris telnet.
-- 
View this message in context: http://www.nabble.com/TextLineDecoder-decode-function-tf4142835s16868.html#a11806556
Sent from the Apache MINA Support Forum mailing list archive at Nabble.com.


Re: TextLineDecoder decode function

Posted by Trustin Lee <tr...@gmail.com>.
On 7/26/07, Mark Webb <el...@gmail.com> wrote:
> I have seen the same thing on windows when using telnet using the MINA
> EchoServer example program.  I think it is a windows, not MINA issue.

Yep.  Windows telnet client flushes every keystroke, while *NIX telnet
clients flush on a carrage return.

> On 7/25/07, alimli <ha...@gmail.com> wrote:
> >
> >
> > Hi,
> > First, I want to mention that I'm new to Java. So I'm asking some silly
> > question don't blame me. :)
> >
> > I wrote a subclass of TextLineDecoder and override decode function. Code
> > looks like below
> >
> > public class CaiRequestDecoder extends  TextLineDecoder {
> >
> >     private CharsetDecoder _decoder = Charset.forName
> > ("ASCII").newDecoder();
> >
> >     /** Creates a new instance of CaiRequestDecoder */
> >     public CaiRequestDecoder() {
> >         super(Charset.forName("ASCII"), LineDelimiter.MAC);
> >     }
> >
> >     public void decode(IoSession session, ByteBuffer in,
> >             ProtocolDecoderOutput out) throws Exception {
> >         // Try to decode body
> >         try {
> >             CaiRequestMessage m = decodeBody(in);
> >             out.write(m);
> >         } catch(ProtocolDecoderException ex) {
> > //            session.write("RESP-1").join();
> > //            session.close();
> >         }
> >     }
> >
> >     private CaiRequestMessage decodeBody(ByteBuffer in) throws
> > ProtocolDecoderException  {
> >         String inStr = "";
> >         try {
> >             inStr = in.getString(_decoder);
> >             System.out.println("Buffer String :" + inStr);
> >             CaiRequestMessage request = parseRequest(new
> > StringReader(inStr));
> >             return request;
> >         } catch (CharacterCodingException ex) {
> >             ex.printStackTrace();
> >             return null;
> >         }
> >     }

You are using TextLineDecoder in a wrong way.  I'd suggest the
following implementation:

1) Use TextLineDecoder as it is; do not extend it.
2) Once you inserted your protocol codec filter, your IoHandler's
messageReceived() will be provided with a line of string.

HTH,
Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP Key ID: 0x0255ECA6

Re: TextLineDecoder decode function

Posted by Mark Webb <el...@gmail.com>.
I have seen the same thing on windows when using telnet using the MINA
EchoServer example program.  I think it is a windows, not MINA issue.


On 7/25/07, alimli <ha...@gmail.com> wrote:
>
>
> Hi,
> First, I want to mention that I'm new to Java. So I'm asking some silly
> question don't blame me. :)
>
> I wrote a subclass of TextLineDecoder and override decode function. Code
> looks like below
>
> public class CaiRequestDecoder extends  TextLineDecoder {
>
>     private CharsetDecoder _decoder = Charset.forName
> ("ASCII").newDecoder();
>
>     /** Creates a new instance of CaiRequestDecoder */
>     public CaiRequestDecoder() {
>         super(Charset.forName("ASCII"), LineDelimiter.MAC);
>     }
>
>     public void decode(IoSession session, ByteBuffer in,
>             ProtocolDecoderOutput out) throws Exception {
>         // Try to decode body
>         try {
>             CaiRequestMessage m = decodeBody(in);
>             out.write(m);
>         } catch(ProtocolDecoderException ex) {
> //            session.write("RESP-1").join();
> //            session.close();
>         }
>     }
>
>     private CaiRequestMessage decodeBody(ByteBuffer in) throws
> ProtocolDecoderException  {
>         String inStr = "";
>         try {
>             inStr = in.getString(_decoder);
>             System.out.println("Buffer String :" + inStr);
>             CaiRequestMessage request = parseRequest(new
> StringReader(inStr));
>             return request;
>         } catch (CharacterCodingException ex) {
>             ex.printStackTrace();
>             return null;
>         }
>     }
>
> When I telnet my application for testing from a Solaris machine, I type
> the
> input and press enter. Then my decode function is called. All is fine.
>
> But when I try to telnet from windows and type sth. Every key triggers my
> decode function. And HeapBuffer's limit is always 1. Only the last
> character
> is returned from in.getString();
>
> Is it sth. wrong with my code? I expect TextLineDecoder will only call
> decode when a line is completed? Isn't this the default behaviour?
>
> Thanks.
> --
> View this message in context:
> http://www.nabble.com/TextLineDecoder-decode-function-tf4142835s16868.html#a11784785
> Sent from the Apache MINA Support Forum mailing list archive at Nabble.com
> .
>
>


-- 
..Cheers
Mark