MIDP终端模拟之一:一个简单的模拟器MIDlet[2]

[入库:2006年2月23日] [更新:2007年3月24日]

本文简介:

  • WILL 提出第一方能够和原意执行的选项。如果第一方应该开始执行那个选项,则另一方回复 D0,如果另一方无法理解或不支持该选项,则回复 DONT。
  • DO 告诉另一方开始执行选项。如果另一方开始执行选项,则回复 WILL,如果另一方无法理解或不支持该选项,则回复 WONT。

我们最小的客户端将只处理 4 条命令:WILL、WONT、DODONT,以及两个选项:TERMINAL_TYPE(24)和 NAWS(“协商窗口大小” 31)。对于所有其他选项,我们将返回 DONTWONT。(我曾考虑支持 RANDOMLY_LOSE_DATA(256)和 SUBLIMINAL_MESSAGE(257)选项,但是我们现在尽量保持其简单。)

Telnet 输入流

要查看以代码表示的协议,可以看看 TelnetInputStream.java 的清单。最令人兴奋的是 read() 方法。在这个摘录中,我去除了某些细节:

public int read() throws IOException
{
    byte b;
    
    b = (byte) input.read();
    if ( b != IAC ) return b; // not an IAC, skip.
    
    b = (byte) input.read();
    if ( b == IAC ) return b; // two IACs isn't.
    
    if ( b != SB ) // handle command
    {
        switch ( b )
        {
            // basic commands
            case   GA:
            case  NOP:
            case  DAT:
            case  BRK:
            case   IP:
            case   AO:
            case  AYT:
            case   EC:
            case   EL:
                // not implemented: ignore for now
                System.err.println( 
                    "Ignored command: " 
                    + b + " : " + reply[2] );
                return read();
                
            // option prefixes
            case   DO:
            case DONT:
            case WILL:
            case WONT:
                // read next byte to determine option
                reply[2] = (byte) input.read();
                switch ( reply[2] )
                {
                    case TERMINAL_TYPE:
                        ...
                    
                    case WINDOW_SIZE:
                        ...
                    
                    default:
                        // unsupported option: break
                        ...
                }
                break;
                
            default:
                // unsupported option: suppress and exit
                System.err.println( 
                    "Unsupported command: " + b );
        }
    }
    else // handle begin-sub
    {
        b = (byte) input.read();
        reply[2] = b;
        switch ( b )
        {
            case TERMINAL_TYPE:
                ...
            default:
                reply[1] = WONT;
                write( reply );
        }
    }
    
    return read();
}

因为我们忽略了所有的内容而只留下协商命令和多数选项,所以当我们接收到针对 TERMINAL_TYPENAWS 的 D0 命令时,感兴趣的部分才开始了。

对于 TERMINAL_TYPE,我们设法对我们和另一端都支持哪种传统的终端达成一致意见。某些基于终端的应用程序将利用更高级终端类型的特性,如颜色、粗体和下划线。更为复杂的终端模拟器将模拟多种终端类型,如 ansivt100vt102。协商就是设法建立最佳的共同点。最简单的终端类型称为哑终端,这也是我们将支持的一种。

如果我们接收到 IAC DO TERMINAL_TYPE,我们用 IAC WILL TERMINAL_TYPE 响应。依照 RFC 1091 规范,然后远程主机就开始与 IAC SB TERMINAL_TYPE TERMINAL_SEND IAC SE 的子协商,然后我们响应 IAC SB TERMINAL_TYPE TERMINAL_IS d u m b IAC SE

    ...
    case TERMINAL_TYPE:
        ...
        reply[1] = SB;
        write( reply );
        char[] c = terminal.toCharArray();
        byte[] bytes = new byte[c.length+3];
        int i = 0;
        bytes[i++] = TERMINAL_IS;
        for ( ; i < c.length+1; i++ ) 
        {
            bytes[i] = (byte) c[i-1];
        }
        bytes[i++] = IAC;
        bytes[i++] = SE;
        write( bytes );
        break;

    ...

本文关键:MIDP终端模拟之一:一个简单的模拟器MIDlet
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top