首先介绍基本的单字符方式,该方式类似于Rlogin。用户在终端输入的每个字符都将由终端发送到服务器进程,服务器进程的响应也将以字符方式回显到终端上。在这里运行的是一个新的客户进程BSD/386,它试图激活很多新的选项,服务器进程还是运行老的SVR4,我们将看到很多选项被服务器拒绝。
为了看到服务器和客户机之间选项协商的内容,我们将激活客户进程的一个选项来显示所有的选项协商。同样我们运行tcpdump来获得数据报交换的时间次序。图26-12显示了这个交互会话。
在图中,我们已经对由SENT或RCVD开头的选项协商的每一步都进行了标注。关于每一步的解释如下:
1)客户发起SUPPRESSGOAHEAD选项协商。由于GOAHEAD命令通常是由服务器发送给客户的,而且客户希望服务器激活该选项,因此该选项的请求方式是DO(由于激活这一选项将会禁止GA命令的发送,上述过程很轻易让人混淆)。在第10行可以看到服务器进程同意该选项。
2)客户进程要按照在RFC1091[VanBokkelen1989]中的定义发送终端类型。这对Unix类型的客户进程来讲是很普通的。因为客户进程要激活本地的选项,所以该选项的请求方式是WILL。
调用客户进程,不带任何命令行选项告诉客户进程显示所有的选项协商过程,现在和服务器建立连接,我们键入用户和口令,服务进程不回显这些数据,然后操作系统问候输出,然后是外壳提示符。
Telnet双方选项协商的初始化过程
3)NAWS的意思是“协商窗口大小”,它在RFC1073[Waitzman]中有定义。假如服务器进程同意该选项(实际上不同意,见11行),客户进程就要发送终端窗口的行、列大小的子选项。而且只要窗口大小发生变化,客户进程随时都将向服务器进程发送这一子选项(这和图26-4中Rlogin的0x80命令类似)。
4)TSPEED选项答应发送方(通常是客户进程)发送它的终端速率,这在RFC1079[Hedrick1988b]中有定义。假如服务器进程同意(实际上不同意,见12行),客户进程将发送其发送速率和接收速率的子选项。
5)LFLOW代表“本地流量控制”,这在RFC1371[Hedrick和Borman1992]中定义。客户进程给服务器进程发送该选项,表示客户进程希望用命令方式激活或禁止流量控制。假如服务器进程同意(实际上不同意,见13行),只要Control_S和Control_Q进程需要在客户进程和服务器进程进行切换,客户进程都要向服务器进程发送子选项(这类似于图26-4中Rlogin的0x10和0x20命令)。正如在关于Rlogin的讨论中我们所提到的那样,由客户进程进行流量控制的效果比由服务器进程来完成要好。
6)LINEMODE代表在26.4中所说的实行方式。所有终端字符的处理由Telnet客户进程完成(例如回格,删除行等),然后整行发送给服务器进程。在本节后面,我们将介绍一个例子。该选项同样被服务器进程拒绝,如14行所示。7)ENVIRON选项答应客户进程把环境变量发送给服务器进程,这在RFC1408[Borman1993a]中有定义。这样就可以把客户进程的用户环境变量自动传播到服务器进程。在15行,服务器进程拒绝该选项(Unix中的环境变量通常是大写字母,紧跟一个等号,然后是一个字符串值,当然这只是一个惯例而已)。默认情况下,BSD/386Telnet客户进程发送两个环境变量:DISPLAY和PRINTER,前提是这两个变量已经定义并且有效。Telnet用户可以定义其他一些要发送的环境变量。
8)STATUS选项(RFC859[Postel和Reynolds1983e]中定义)答应连接的一方询问对方对Telnet选项目前状态的理解。在这个例子中,客户进程要求对方激活选项(DO)。假如服务器进程同意(实际上不同意,见16行),客户进程就可以要求服务器进程以子选项的形式发送它的状态值。
9)这是服务器进程的第一个响应。服务器进程同意激活终端类型选项(几乎所有的Unix类型的服务器进程都支持该选项)。但现在客户进程还不能立即发送它的终端类型。它必须要等到服务器进程用子选项的形式询问终端类型的时候才能够发送(17行)。
10)服务器进程同意抑制发送GOAHEAD命令。11)服务器进程不同意客户进程发送它的窗口大小。12)服务器进程不同意客户进程发送它的终端速率。13)服务器进程不同意客户进程实施流量控制。14)服务器进程不同意客户进程激活行方式选项。15)服务器进程不同意客户进程发送环境变量。16)服务器进程不发送状态信息。17)这是服务器进程要求客户进程发送终端类型的子选项。18)客户进程把终端类型“IBMPC3”以6字节的字符串形式发送给服务器进程。19)服务器进程要求客户进程发起请求,要求服务器进程激活回显选项。这是本例中服务器进程第一次主动发起选项协商。20)客户进程同意由服务器进程实现回显功能。21)服务器进程要求客户进程实现回显功能。这个命令是多余的,它只是将前两行进行了交换。这是目前大多数Unix的Telnet服务器进程判定客户进程是否运行4.2BSD或更新的BSD版本时的一个方法。假如客户进程回送WILLECHO,就表明客户进程运行的是老版本的
4.2BSD,不支持TCP的紧急方式(在这种情况下就不能采用TCP紧急方式)。22)客户进程回送WONTECHO,表示它不是一台4.2BSD主机。23)对于客户进程回送的WONTECHO,服务器进程以DONTECHO作为响应。图26-13显示的是本例中服务器进程和客户进程交互的时间系列(去掉了连接建立部分)。报文段1包含了图26-12中的1~8行。该报文段中包含24个字节数据,每个选项占3个字节。这是客户进程发起的选项协商。该报文段显示多个Telnet选项可以打在一个TCP段中发送。报文段3是图26-12中的第9行,即DOTERMINALTYPE命令。报文段5包含下面的8个选项协商中服务器进程的响应,即图26-12中的10~17行。该报文段的长度是27个字节,因为10~16行是常规选项,每个占3个字节,而17行的子选项部分占6个字节。报文段6包含12个字节,和18行对应,这是客户发送它的终端类型的子选项。报文段8(53个字节)包含两个Telnet命令和47字节的输出数据。前面的两个服务器进程发送Telnet命令占6字节,:WILLECHO和DOECHO(19和21行)。后47个字节的数据是:\r\n\r\nUNIX(r)SystemVRelease4.0(svr4)\r\n\r\0\r\n\r\0前面4个字节数据在字符串输出之前产生两个空行。两字节的字符序列“\r\n”在Telnet中被认为是换行命令,而两字节的字符序列“\r\0”则被认为是回车命令。这表明数据和命令可以在一个数据段中传输。Telnet服务器进程和客户进程必须扫描接收到的每个字符,寻找IAC字节并执行它后续的命令。
图26-13Telnet服务器进程和客户进程选项协商初始化过程
报文段9包含客户进程发送的最后两个选项:20和22行。23行是报文段10的响应,也是服务器进程发送的最后一个选项数据。
从现在开始,双方就可以交互数据了。当然在交互数据的过程中还可以进行选项协商,我们在该例子中就不多介绍了。报文段12是服务器进程发送的提示符“login:”。报文段14是用户输入的登录用户名的第一个字符,它的回显在报文段15中。这和我们在19.2节中介绍的Rlogin交互类似:客户进程每次发送一个字符,服务器进程完成回显工作。
图26-12中的选项协商由客户进程初始化的,但是在本书中我们已经介绍了用Telnet客户进程连接某些标准服务器进程如:日间(daytime)服务器、回显(echo)服务器等情况。当然我们介绍这些的目的是为了描述TCP的各种特性。但考察这些例子中的分组交换,如图18-1,我们并没有看到客户进程发起的选项协商。为什么?这是因为在Unix系统中,除非使用标准的Telnet端口号23,否则客户进程不进行选项协商。这个特性使得Telnet客户进程可以使用标准的NVT同其他一些非Telnet服务器进程交换数据。我们已经在日间服务器、回显服务器和丢弃(discard)服务器中使用了这个特性,在后面章节介绍FTP和SMTP服务器的时候我们还将使用该特性。