现在的位置: 首页 > 综合 > 正文

为在telnet自己TCP服务器程序的界面上实现shell一样的自动补齐和历史记录的功能。

2013年10月15日 ⁄ 综合 ⁄ 共 8148字 ⁄ 字号 评论关闭

1. 目的

希望在 telnet 自己 TCP 服务器程序的界面上实现 shell 一样的自动补齐和历史记录的功能。

2. 问题

程序的远程登陆的 telnet 界面通常是通过一个 TCP 服务器来实现的,但是如果想在这个 TCP 服务器端实现客户端登陆界面的自动补齐和历史记录的功能会有如下的问题:

1 )常见的 telnet 客户端是以行模式发送数据的,即输入一个字符串后再按一个回车,整个数据才会被发送到服务器端。

2 )常见的 telnet 客户端是自动回显的,即你在键盘上输入一个字符后,客户端自己将这个字符显示在客户端界面上,而不是显示的从服务器端发送过来的数据。

默认这样做的原因,是为了简化了客户端和服务器端的实现。但是如果希望能够让客户端能够具有 shell 一样的自动补齐和历史记录功能则无法实现,原因如下:

1 )自动补齐功能一般是按 tab 键后按现有输入的部分进行匹配的,不能等按回车,因为按回车一般表示客户端输入完成,等待服务器处理的结果。应该是按下每个按键都发送一次。

2 )历史记录功能一般有按 键来实现对记录上翻和下翻的功能,而如上翻功能在按下 键后应用上条历史记录来替代当前行输入的值,这就需要抹除当前行已有的字符,这点在自动回显的功能中很难做到。换句话说,最好由服务器端完全控制客户端的显示,不要让客户端自动显示任何东西。

 

3. 解决办法

按照 telnet 协议的规定,详见附录1,将回显功能关闭,将输入模式从逐行模式改为逐个字符模式。具体参考 命令参考大全。

echo

在输入字符的本地屏幕显示与禁止本地屏幕显示间切换。本地屏幕显示用于正常处理,而禁止屏幕显示便于输入不宜显示在屏幕上的文本,如密码。该变量仅可用于逐行方式

输入方式

当带参数发出 telnet 命令时,它执行包含这些参数的 open 子命令,然后进入输入方式。输入方式的类型为逐个字母或逐行,取决于远程系统所支持的是什么。在逐个字母方式下,大部分输入的文本会立即送到远程主机处理。在逐行方式下,所有文本在本地屏幕显示,然后将完整的行发送到远程主机。

这样做增加了客户端和服务端实现的工作量,尤其是服务器端,需要对接收的字符进行拼装处理,同时要控制客户端的显示。主要实现功能如下:

1 )实现对客户端显示的控制功能,因为客户端不再自动显示,一些原有的功能现在需要由服务器来完成,比如删除一个字符,现在服务器需要三步完成: 1. 发送指令让客户端的光标向前移动一个字符 à 2. 向客户端发送一个空格 à 3. 再发送指令让客户端的光标向前移动一个字符。

2 )在服务器端对接收到的数据进行缓存和管理,根据收到的数据对前面的数据做对应的处理。如收到一个删除字符就要将缓存的字符串最后一个字符删除并将长度减一并进行( 1 )提到的操作。

3 )实现自动补齐算法,主要包括两种情况: A. 如果和现有输入匹配的命令只有一个,直接用其在当前行替代已有输入。 B. 如果和现有输入匹配的命令有多个,一般是在当前行下面将这多个命令显示。

4 )对历史记录的管理。

 

4. 具体实现

整体实现参考了 zebra 源代码部分的 telnet 部分的实现,但是 zebra 源码实现的较为复杂,功能虽强,但超出我当前的需求代价太大,故参考简化实现。只在 linux 下的 telnet 测试通过, windows 下可能有点小问题。具体的怎样将命令执行参考 asterisk 源码中 cli 的实现简化实现,感觉 asterisk cli 的设计思路更加清晰些,但是只支持本地显示,不能 telnet

大概代码如下,省略部分

 

  

5 相关参考

1. telnet 协议介绍 http://support.microsoft.com/kb/231866/en-us/

2. zebra Zebra  是一个开源的  TCP/IP  路由软件,同  Cisco Internet  网络操作系统( IOS )类似。详见 http://www.zebra.org/

3. asterisk 是一个开源的软 PBX 软件。详见 http://www.asterisk.org/

 

 

抱歉!评论已关闭.