作者:Michael 文章来源:SUN中国技术社区
下载 项目源代码
随着每一款新的 MIDP 2.0 设备在高级网络上部署,基于 TCP/IP 的套接字应用程序市场正不断得到扩展。它是对 MIDP 1.0 设备的补充,这些设备要么已经完全支持可选的套接字协议(像 Motorola/Nextel iDEN 电话),或者至少非正式地在半双工中支持它们(像 Nokia Series 60 和其他 Symbian 设备)。结果,随着有企业头脑的开发人员发现该平台不仅可以很好地用于游戏,他们对它也表现出越来越强的兴趣。
在本文中,通过构建一个小的简单终端模拟器,我们将探讨通用连接框架(GCF)中的套接字支持。您现在可以下载项目代码了。
我们的终端模拟器将实现 telnet 协议。telnet 协议是基于文本的和面向命令的协议,它是 Internet 的架构骨干之一,并且广泛用于教育、研究和公司环境中的遗留应用程序和系统管理。在移动形式中具有该功能是一件很好的事情。
我们将首先在一个透明和 GCF 友好的包装器中实现 telnet,然后为显示终端内容而编写一个自定义的 canvas,并最终在 MIDlet 中将所有这些结合在一起。在“让它工作,然后再让它正确”的精神下,我们要使一个最基本的(或者叫“哑”)终端工作,并且这将作为稍后更为复杂终端的基础。同时,我将突出说明 MIDP 程序员在编写普通应用程序以及网络化应用程序时应该知晓的问题和约束。
Telnet:它对什么有好处?
telnet 协议是一个用于在双向网络连接上进行通信的规则集。与来回传送的普通内容相混合的是特殊的 telnet 命令 ,该命令允许连接的两端进行协商并同意将要遵守的规则。这些命令从进入数据中剥离,所以使用该接的应用程序永远无需知道它们。
Telnet 早于现代 Internet 而出现。J. Postel 和 J. Reynolds 于 20 多年前在 RFC 854 (值得一读)中定义了该协议。在那时,“终端”意味着一个屏幕和键盘,使用串行电缆连接到大型计算机。要使用终端,您必须与计算机处于同一座建筑中。Telnet 则允许您将终端连接到网络中,然后在 Internet 上从任何地方进行工作。
Telnet 使您能控制任何具有命令行界面的操作系统。在 UNIX 环境中,您可以获得对机器的完全控制,包括能够开始和停止处理,甚至关机和重新启动。实际上,多数 UNIX 软件都假定用户是在终端上。在 WWW 出现之前,telnet 还提供我们现在称作 Web 服务的信息和服务类型,这些 telnet 服务中的某些仍旧可用,如 Weather Underground。但是,现今 telnet 主要用于对远程计算资源的远程访问。
几乎没有人再使用老式的终端了:在桌面计算机、智能工作站以及越来越多地在移动设备上,我们运行着“假装”是终端的软件程序,称为“虚拟终端”或“终端模拟器”。这正是我们将要构建的。
实现 Telnet
首先从 InputStream 开始。有了 GCF,利用类似于 Connector.open("socket://myhost:23") 这样的代码,您可以从 Connector 处获得一个 SocketConnection。然后从所得到的 Connection 调用 openInputStream() 来获得一个 InputStream ,并开始从套接字读取数据。
要实现 telnet,我们需要观察该命令流并处理它们,将其剥离出来,使应用程序的其他部分永远看不到它们。我们将通过创建我们自己的子类 InputStream 来这样做,该子类将包装从 SocketConnection 处获得的流。我们还将创建我们自己的 OutputStream 子类,用来标记我们的应用程序所发送的看来像是 telnet 命令、但又不应被连接的远程端看作是 telnet 命令的任何数据。
换句话说,我们的应用程序将像通常那样简单地与输入和输出流对话,而在内部,我们的终端模拟器将处理握手和协商,所以应用程序无需担心这些。
我们的 telnet 模拟器必须遵循一个典型性的过程:
我们从输入读取一个字节。如果该字节是除 225 以外的任意数值,我们只需把该字节传送到应用程序并继续读取。
如果字节数值是 255,那么我们就读取下个字节,查看它是否是一条命令。在 telnet 协议中,255 作为 IAC,代表“作为命令解释”(Interpret As Command)。
如果第二个字节还是 255,那么服务器实际上是想发送数值 255,不是一条命令。在这种情况下,我们只需把该字节传送到应用程序并继续读取。实际上,发送者通过连续发送两个 255 来转义数值 255。
如果第二个字节不是 255,它就是一条命令。对于多数命令,我们只要执行命令内容并继续读取即可。
某些命令 ——如
SB(250)、WILL(251)、WONT(252)、DO(253)和DONT(254)——是协商命令。每个命令后都跟随着第三个字节-选项,我们读取那个字节,获得选项代码。如果第二个字节是除 SB 以外的任何协商命令,我们执行命令和选项所指定的操作并继续读取。
SB命令会触发一个子协商。在选项字节后,我们读取其他数据,直到我们遇到一个后面跟有 SE 的 IAC。我们执行选项所指定的操作,使用所提供的额外信息,并继续读取。
因为客户端无需决定它们将要实现哪些已建立的 telnet 选项,所以在客户端和服务器间必须进行协商,以确定两端支持哪些选项。
协商是简单的命令交换。一端使用 WILL 或 D0 命令打开一个协商,使用哪条命令取决于由哪一方执行指定的选项: