摘要:本文简单介绍了TELNET协议产生背景,协议原理,包括协议的三个主体:网络虚拟终端,操作协商定义,协商有限自动机
1、 协议产生的背景
一个直接连到主机上的终端能够很容易地登录到本地系统中。这种能力的自然扩展就是同样的终端也能够访问远程系统。那些分布式应用,象数据库、文件或者打印机,都是能够以原始方式共享的资源。而提出的挑战就是定义并实现一个标准,使这些应用能够支持目前广泛使用的各种类型的终端。
目前有两个主要的协议标准用来访问远程应用:
Relogin
Telnet(RFC854)
Relogin是为Berkeley UNIX而开发的,它是一个相对简单和稳定的协议,一直被UNIX团体以外的用户采用。而TELNET则是一个功能丰富的TCP/IP标准。
2 TELNET协议
2.1 概述
Telnet协议是TCP/IP协议族中应用最广泛的协议。提供一个以连机方式访问网际网上资源的通用工具,它允许用户与一个远程机器上的服务器进行通信,通过一个协商过程来支持不同的物理终端,从而提供了极大的灵活性。下图是TELNET客户机和服务器的典型结构。
图1 Telnet 客户机和服务器结构概况
用户首先登录到他的本地系统,然后在本地键入TELNET命令,后面跟上远程主机的参数,如下:
Telnet HostName
![]()
在将域名(HOSTNAME)转换为IP地址后,本地主机就通过众所周知(即系统保留)的端口23同远程TELNET服务器建立一个TCP连接,此时,数据可以通过网络在两个系统之间传输,在这一点上,远程应用在用户看来就象在本地一样。
下图给出了一个TELNET CLIENT会话的典型结构。
图 TELNET客户机连接
所以,TELNET客户机必须同时完成两件事:
1)客户机必须读取用户在键盘上键入的字符,并在TCP连接上把他们发送到远程服务器上去。
2)客户机必须读取从TCP连接上达到的字符,并把他们显示在用户的终端屏幕上。
2.2 TELNET协议原理
在协议产生的背景中就指出TELNET协议的主要工作是使各种应用能够支持目前广泛使用的各种类型的终端;TELNET通过将终端映射为一个逻辑设备,采用一致的标准,从而使不同的终端类型进行客户到服务器间的数据交换。
TELNET协议的主体由三个部分组成:
Ÿ 网络虚拟终端(NVT,Network Virtual Terminal)的定义;
Ÿ 操作协商定义;
Ÿ 协商有限自动机;
2.2.1 网络虚拟终端(NVT)
Ÿ NVT工作原理
顾名思义,网络虚拟终端(NVT)是一种虚拟的终端设备,它被客户和服务
器所采用,用来建立数据表示和解释的一致性。
Ÿ NVT的定义
1)NVT的组成
网络虚拟终端NVT包括两个部分:
输出设备:输出远程数据,一般为显示器
输入设备:本地数据输入
2)在NVT上传输的数据格式
在网络虚拟终端NVT上传输的数据采用8bit字节数据,其中
最高位为0的字节:一般数据
最高位为1的字节:用于NVT命令
3)NVT在TELNET中的使用
TELNET使用了一种对称的数据表示,当每个客户机发送数据时,把它的本地终端的字符表示影射到NVT的字符表示上,当接收数据时,又把NVT的表示映射到本地字符集合上。
在通信开始时,通信双方都支持一个基本的NVT终端特性子集(只能区分何为数据,何为命令),以便在最低层次上通信,在这个基础上,双方通过NVT命令协商确定NVT的更高层次上的特性,实现对NVT功能的扩展。
在TELNET中存在大量的子协议用于协商扩展基本的网络虚拟终端NVT的功能,由于终端类型的多样化,使得TELNET协议族变得庞大起来。
2.2.2 操作协商
1)为什么要协商操作选项
当定义了网络虚拟终端设备后,通信的双方就可以在一个较低的层次上实现数据通信,但基本的NVT设备所具有的特性是十分有限的,它只能接收和显示7位的ASCII码,没有最基本的编辑能力,所以简单的NVT设备是没有实际应用意义的;为此TELNET协议定义了一族协议用于扩展基本NVT的功能,目的是使NVT能够最大限度地达到用户终端所具有的功能。
为了实现对多种终端特性的支持,TELNET协议规定在扩展NVT功能时采用协商的机制,只有通信双方通过协商后达成一致的特性才能使用,才能赋予NVT该项特性,这样就可以支持具有不同终端特性的终端设备可以互连,保证他们是工作在他们自己的能力以内。
2)操作协商命令格式
TELNET的操作协商使用NVT命令,即最高位为1的字节流,每条NVT命令以字节IAC(0xFF)开始。原理如下:
只要客户机或服务器要发送命令序列而不是数据流,它就在数据流中插入一个特殊的保留字符,该保留字符叫做“解释为命令”(IAC ,Interpret As Command) 字符。当接收方在一个入数据流中发现IAC字符时,它就把后继的字节处理为一个命令序列。下面列出了所有的Telnet NVT命令,其中很少用到。
表1 TELNET 命令
|
名称 |
编码 |
说明 |
|
EOF |
236 |
文件结束符 |
|
SUSP |
237 |
挂起当前进程 |
|
ABORT |
238 |
中止进程 |
|
EOR |
239 |
记录结束符 |
|
SE |
240 |
子选项结束 |
|
NOP |
241 |
空操作 |
|
DM |
242 |
数据标记 |
|
BRK |
243 |
终止符(break) |
|
IP |
244 |
终止进程 |
|
AO |
245 |
终止输出 |
|
AYT |
246 |
请求应答 |
|
EC |
247 |
终止符 |
|
EL |
248 |
擦除一行 |
|
GA |
249 |
继续 |
|
SB |
250 |
子选项开始 |
|
WILL |
251 |
选项协商 |
|
WONT |
252 |
选项协商 |
|
DO |
253 |
选项协商 |
|
DONT |
254 |
选项协商 |
|
IAC |
255 |
字符0XFF |
其中常用的TELNET选项协商如下:
WILL XXX:我想具有XXX特性,你是否同意;
WONT XXX:我不想具有XXX特性
DO XXX:我同意你可以具有XXX特性
DON'T XXX:我不同意你具有XXX特性
那么对于接收方和发送方有以下几种组合:
表2 TELNET 选项协商的六种情况
|
发送者 |
接收者 |
说明 |
|
WILL |
DO |
发送者想激活某选项,接受者接收该选项请求 |
|
WILL |
DONT |
发送者想激活某选项,接受者拒绝该选项请求 |
|
DO |
WILL |
发送者希望接收者激活某选项,接受者接受该请求 |
|
DO |
DONT |
发送者希望接收者激活某选项,接受者拒绝该请求 |
|
WONT |
DONT |
发送者希望使某选项无效,接受者必须接受该请求 |
|
DONT |
WONT |
发送者希望对方使某选项无效,接受者必须接受该请求 |
选项协商需要3个字节:IAC,然后是WILL、DO、WONT或DONT;最后一个标识字节用来指明操作的选项。常用的选项代码如下:
表3 TELNET 选项代码
|
选项标识 |
名称 |
RFC |
|
1 |
回应(echo) |
857 |
|
3 |
禁止继续 |
858 |
|
5 |
状态 |
859 |
|
6 |
时钟标识 |
860 |
|
24 |
终端类型 |
1,091 |
|
31 |
窗口大小 |
1,073 |
|
32 |
终端速率 |
1,079 |
|
33 |
远端流量控制 |
1,372 |
|
34 |
行模式 |
1,184 |
|
36 |
环境变量 |
1,408 |
选项协商举例:
通常情况下,客户机向服务器发送字符而服务器将其回显到用户的终端上,但是,如果网络的时延回引起回显速度太慢,用户可能更愿意让本地系统回显字符。在客户机允许本地系统回显前,它要向服务器发送以下序列:
IAC DONT ECHO
服务器收到请求后,发出3个字符的响应:
IAC WONT ECHO
表示服务器已经按请求同意关闭回显。
2.2.3 子选项协商
除了“打开”或“关闭”以外,有些选项还需要更多的信息,例如对于指明终端类型来说,客户必须发送一个字符串来标识终端类型,所以要定义子选项协商。
RFC 1091定义了终端类型的子选项协商。举个例子:
客户发送字节序列来请求打开选项:
< IAC,WILL,24>
24是终端类型的选项标识符。如果服务器同意该请求,响应为:
< IAC,DO,24 >
接着服务器发送
< IAC,SB,24,1,IAC,SE>请求客户给出其终端类型。
SB是子选项开始命令,下一个字节24表示该子选项为终端类型选项。下一个字节1表示:发送你的终端类型。客户的响应为:
< IAC,SB,24,0,'I','B','M','P','C', IAC,SE>
第四个字节0的含义是“我的终端类型为”。
2.3 协议的实现
整个协议软件分为三个模块,各模块的功能如下:
(1) 与本地用户的输入/输出模块:处理用户输入/输出,
(2) 与远地系统的输入/输出模块:处理与远程系统输入/输出;
(3) TELNET协议模块:实现TELNET协议,维护协议状态机;
2.4 与SOCKET层的接口
2.4.1 同步阻塞式实现接口(标准接口)
1、 建立SOCKET: socket( )
2、 利用该SOCKET建立TCP连接:connect(socket)
3、 对SOCKET的读写操作:
READ(SOCKET,BUFFER,LEN)
WERITE(SOCKET,BUFFER,LEN)
SELECT
2.4.2 异步事件加消息实现方式(非标准,VRP协议栈特有)
客户端调用connect主动向服务器发出建立连接请求,然后客户端等待连接请求结果的消息,若消息是ASYN_CONNECT,表示连接建立成功。同样,客户端还要接收有数据到达的消息和对端关闭SOCKET连接的消息。