26.1 引言
遠(yuǎn)程登錄(Remote Login)是Internet上最廣泛的應(yīng)用之一。我們可以先登錄(即注冊(cè))到一臺(tái)主機(jī)然后再通過網(wǎng)絡(luò)遠(yuǎn)程登錄到任何其他一臺(tái)網(wǎng)絡(luò)主機(jī)上去,而不需要為每一臺(tái)主機(jī)連接一個(gè)硬件終端(當(dāng)然必須有登錄帳號(hào))证膨。
在TCP/IP網(wǎng)絡(luò)上,有兩種應(yīng)用提供遠(yuǎn)程登錄功能鼓黔。
1:Telnet是標(biāo)準(zhǔn)的提供遠(yuǎn)程登錄功能的應(yīng)用央勒,幾乎每個(gè)TCP/IP的實(shí)現(xiàn)都提供這個(gè)功能。它能夠運(yùn)行在不同操作系統(tǒng)的主機(jī)之間澳化。Telnet通過客戶進(jìn)程和服務(wù)器進(jìn)程之間的選項(xiàng)協(xié)商機(jī)制崔步,從而確定通信雙方可以提供的功能特性。
2:Rlogin起源于伯克利Unix缎谷,開始它只能工作在Unix系統(tǒng)之間井濒,現(xiàn)在已經(jīng)可以在其他操作系統(tǒng)上運(yùn)行。
在本章中列林,我們將介紹Telnet和Rlogin瑞你。首先介紹Rlogin,因?yàn)镽login比較簡(jiǎn)單希痴。
Telnet是一種最老的Internet應(yīng)用者甲,起源于1969年的ARPANET。它的名字是“電信網(wǎng)絡(luò)協(xié)議(telecommunication network protocol)”的縮寫詞砌创。
遠(yuǎn)程登錄采用客戶-服務(wù)器模式虏缸。圖26-1顯示的是一個(gè)Telnet客戶和服務(wù)器的典型連接圖(對(duì)于Rlogin的客戶和服務(wù)器連接圖鲫懒,我們可以畫得更加簡(jiǎn)單)。
在這張圖中刽辙,有以下要點(diǎn)需要注意:
1:Telnet客戶進(jìn)程同時(shí)和終端用戶和TCP/IP協(xié)議模塊進(jìn)行交互窥岩。通常我們所鍵入的任何信息的傳輸是通過TCP連接,連接的任何返回信息都輸出到終端上扫倡。
2:Telnet服務(wù)器進(jìn)程經(jīng)常要和一種叫做“偽終端設(shè)備”(pseudo-terminal device)打交道谦秧,至少在Unix系統(tǒng)下是這樣的。這就使得對(duì)于登錄外殼(shell)進(jìn)程來講撵溃,它是被Te lnet服務(wù)器進(jìn)程直接調(diào)用的疚鲤,而且任何運(yùn)行在登錄外殼進(jìn)程處的程序都感覺是直接和一個(gè)終端進(jìn)行交互。對(duì)于像滿屏編輯器這樣的應(yīng)用來講缘挑,就像直接在和終端打交道一樣集歇。實(shí)際上,如何對(duì)服務(wù)器進(jìn)程的登錄外殼進(jìn)程進(jìn)行處理语淘,使得它好像在直接和終端交互诲宇,往往是編寫遠(yuǎn)程登錄服務(wù)器進(jìn)程程序中最困難的方面之一。
3:僅僅使用了一條TCP連接惶翻。由于客戶進(jìn)程必須多次和服務(wù)器進(jìn)程進(jìn)行通信(反之亦然)姑蓝,這就必然需要某些方法,來描繪在連接上傳輸?shù)拿詈陀脩魯?shù)據(jù)吕粗。我們?cè)诤竺娴膬?nèi)容中會(huì)介紹Telnet和Rlogin是如何處理這個(gè)問題的纺荧。
4:注意在圖26-1中,我們用虛線框把終端驅(qū)動(dòng)進(jìn)程和偽終端驅(qū)動(dòng)進(jìn)程框了起來颅筋。在TCP/IP實(shí)現(xiàn)中宙暇,虛線框的內(nèi)容一般是操作系統(tǒng)內(nèi)核的一部分。Telnet客戶進(jìn)程和服務(wù)器進(jìn)程一般只是屬于用戶應(yīng)用程序议泵。
5:把服務(wù)器進(jìn)程的登錄外殼進(jìn)程畫出來的目的是為了說明:當(dāng)我們想登錄到系統(tǒng)的時(shí)候占贫,必須要有一個(gè)帳號(hào),Telnet和Rlogin都是如此先口。
對(duì)于Telnet和Rlogin型奥,如果比較一下它們客戶進(jìn)程和服務(wù)器進(jìn)程源代碼的數(shù)量,就可以知道這兩者的復(fù)雜程度碉京。圖26-2顯示了伯克利不同版本的Telnet和Rlogin客戶進(jìn)程和服務(wù)器進(jìn)程源代碼的數(shù)量桩引。
現(xiàn)在,不斷有新的Telnet選項(xiàng)被添加到Telnet中去收夸,這就使得Telnet實(shí)現(xiàn)的源代碼數(shù)量大大增加,而Rlogin依然變化不大血崭,還是比較簡(jiǎn)單卧惜。
遠(yuǎn)程登錄不是那種有大量數(shù)據(jù)報(bào)傳輸?shù)膽?yīng)用厘灼。正如我們前面講到的一樣,客戶進(jìn)程和服務(wù)器進(jìn)程交互的分組大多比較小咽瓷。[Paxson 1993]發(fā)現(xiàn)客戶進(jìn)程發(fā)出的字節(jié)數(shù)(用戶在終端上鍵入的信息)和服務(wù)器進(jìn)程端發(fā)出的字節(jié)數(shù)的數(shù)量之比是 1:20设凹。這是因?yàn)槲覀冊(cè)诮K端上鍵入的一條短命令往往令服務(wù)器進(jìn)程端產(chǎn)生很多輸出。
26.2 Rlogin協(xié)議
Rlogin的第一次發(fā)布是在4.2BSD中茅姜,當(dāng)時(shí)它僅能實(shí)現(xiàn)Unix主機(jī)之間的遠(yuǎn)程登錄闪朱。這就使得Rlogin比Telnet簡(jiǎn)單。由于客戶進(jìn)程和服務(wù)器進(jìn)程的操作系統(tǒng)預(yù)先都知道對(duì)方的操作系統(tǒng)類型钻洒,所以就不需要選項(xiàng)協(xié)商機(jī)制奋姿。在過去的幾年中,Rlogin協(xié)議也派生出幾種非Unix環(huán)境的版本素标。
RFC 1282 [Kantor 1991]詳細(xì)說明了Rlogin協(xié)議称诗。類似于選路信息協(xié)議(RIP)的RFC,它是Rlogin用了許多年后才發(fā)布的头遭。[Stevens 1990]的第15章介紹了遠(yuǎn)程登錄的客戶進(jìn)程及服務(wù)器進(jìn)程端的編程寓免,并且給出了Rlogin的客戶進(jìn)程及服務(wù)器進(jìn)程的完整源代碼。[Comer和Stevens 1993]的第25章和第26章給出了Telnet的客戶進(jìn)程的實(shí)現(xiàn)細(xì)節(jié)和源代碼计维。
26.2.1 應(yīng)用進(jìn)程的啟動(dòng)
Rlogin的客戶進(jìn)程和服務(wù)器進(jìn)程使用一個(gè)TCP連接袜香。當(dāng)普通的TCP連接建立完畢之后,客戶進(jìn)程和服務(wù)器進(jìn)程之間將發(fā)生下面所述的動(dòng)作鲫惶。
1:客戶進(jìn)程給服務(wù)器進(jìn)程發(fā)送4個(gè)字符串:(a)一個(gè)字節(jié)的0蜈首;(b)用戶登錄進(jìn)客戶進(jìn)程主機(jī)的登錄名,以一個(gè)字節(jié)的0結(jié)束剑按;(c)登錄服務(wù)器進(jìn)程端主機(jī)的登錄名疾就,以一個(gè)字節(jié)的0結(jié)束;(d)用戶終端類型名艺蝴,緊跟一個(gè)正斜杠“/”猬腰,然后是終端速率,以一個(gè)字節(jié)的0結(jié)束猜敢。在這里需要兩個(gè)登錄名字姑荷,這是因?yàn)橛脩舻卿浛蛻艉头?wù)器的名稱有可能不一樣。由于大多滿屏應(yīng)用程序需要知道終端類型缩擂,所以終端類型也必須發(fā)送到服務(wù)器進(jìn)程鼠冕。發(fā)送終端速率的原因是因?yàn)橛行?yīng)用隨著速率的改變,它的操作也有所變化胯盯。例如vi編輯器懈费,當(dāng)速率比較小的時(shí)候,它的工作窗口也變小博脑。所以它不能永遠(yuǎn)保持同樣大小的窗口憎乙。
2:服務(wù)器進(jìn)程返回一個(gè)字節(jié)的0票罐。
3:服務(wù)器進(jìn)程可以選擇是否要求用戶輸入口令。這個(gè)步驟的數(shù)據(jù)交互沒有什么特別的協(xié)議泞边,而被當(dāng)作是普通的數(shù)據(jù)進(jìn)行傳輸该押。服務(wù)器進(jìn)程給客戶進(jìn)程發(fā)送一個(gè)字符串(顯示在客戶進(jìn)程的屏幕上),通常是password:阵谚。如果在一定的限定時(shí)間內(nèi)(通常是60秒)客戶進(jìn)程沒有輸入口令蚕礼,服務(wù)器進(jìn)程將關(guān)閉該連接。
通成沂玻可以在服務(wù)器進(jìn)程的主目錄(home directory)下生成一個(gè)文件(通常叫 .rhosts)奠蹬,該文件的某些行記錄了一個(gè)主機(jī)名和用戶名。如果從該文件中已經(jīng)記錄的主機(jī)上用已經(jīng)記錄的用戶名進(jìn)行登錄绳矩,服務(wù)器進(jìn)程將不提示我們輸入口令罩润。但是很多關(guān)于安全性的文獻(xiàn),如[Curry 1992]翼馆,強(qiáng)烈建議不要采用這種方法割以,因?yàn)檫@存在安全漏洞。
如果提示輸入口令应媚,那么我們輸入的口令將以明文的形式發(fā)送到服務(wù)器進(jìn)程严沥。我們所鍵入的每個(gè)字符都是以明文的格式傳輸?shù)摹K阅橙酥灰軌蚪厝【W(wǎng)絡(luò)上的原始傳輸?shù)姆纸M中姜,他就可以截獲用戶口令消玄。針對(duì)這個(gè)問題,新版本的Rlogin客戶程序丢胚,例如4.4BSD版本的客戶程序翩瓜,第一次采用了Kerberos安全模型。Kerberos安全模型可以避免用戶口令以明文的形式在網(wǎng)絡(luò)上傳輸携龟。當(dāng)然兔跌,這要求服務(wù)器進(jìn)程也支持Kerberos([Curry 1992]詳細(xì)描述了Kerberos安全模型)。
4:服務(wù)器進(jìn)程通常要給客戶進(jìn)程發(fā)送請(qǐng)求峡蟋,詢問終端的窗口大蟹匚Α(將在后面解釋)。
客戶進(jìn)程每次給服務(wù)器進(jìn)程發(fā)送一個(gè)字節(jié)的內(nèi)容蕊蝗,并且接收服務(wù)器進(jìn)程的所有返回信息仅乓。這在19.2節(jié)中已經(jīng)介紹過了。同樣我們也采用了Nagle算法(在19.4節(jié)中曾經(jīng)介紹)蓬戚,該算法可以保證在速率較低的網(wǎng)絡(luò)上夸楣,若干輸入字節(jié)以單個(gè)TCP報(bào)文段傳輸。操作其實(shí)很簡(jiǎn)單:用戶鍵入的所有東西被發(fā)送到服務(wù)器,服務(wù)器發(fā)送給客戶的任何信息返回到用戶的屏幕上裕偿。
另外洞慎,服務(wù)器和客戶之間還可以互相發(fā)送命令。在介紹這些命令之前嘿棘,先介紹需要用到這些命令的場(chǎng)合。
26.2.2 流量控制
默認(rèn)情況下旭绒,流量控制是由Rlogin的客戶進(jìn)程完成的鸟妙。客戶進(jìn)程能夠識(shí)別用戶鍵入的STO P和STA RT的ASCII字符(Control_S和Control_Q)挥吵,并且終止或啟動(dòng)終端的輸出重父。
如果不是這樣,每次我們?yōu)榻K止終端輸出而鍵入的Control_S字符將沿網(wǎng)絡(luò)傳輸?shù)椒?wù)器進(jìn)程忽匈,這時(shí)服務(wù)器進(jìn)程將停止往網(wǎng)絡(luò)上寫數(shù)據(jù)房午。但是在寫操作終止之前,服務(wù)器進(jìn)程可能已經(jīng)往網(wǎng)絡(luò)上寫了一窗口的輸出數(shù)據(jù)丹允。也就是說郭厌,在輸出停止之前,成千上萬的數(shù)據(jù)字節(jié)還將在屏幕上顯示雕蔽。圖26-3顯示了這個(gè)情況折柠。
對(duì)于一個(gè)交互式用戶來講,Control_S字符的響應(yīng)延時(shí)是較大的批狐。
有時(shí)候扇售,服務(wù)器的應(yīng)用程序需要解釋輸入的每個(gè)字節(jié),但又不想讓客戶對(duì)它的輸入內(nèi)容進(jìn)行處理嚣艇,例如對(duì)控制字符如Control_S和Control_Q進(jìn)行特殊處理(emacs編輯器就是這樣的一個(gè)例子承冰,它把Control_S和Control_C作為自己的命令)。解決這個(gè)問題的辦法就是由服務(wù)器告訴客戶是否要進(jìn)行流量控制食零。
26.2.3 客戶的中斷鍵
當(dāng)我們?yōu)橹袛喾?wù)器正在運(yùn)行的進(jìn)程而鍵入一個(gè)中斷字符時(shí)(通常是DELETE或Control_C)困乒,會(huì)發(fā)生和流量控制相同的問題。這個(gè)情況和圖26-3所示的類似慌洪,在一條TCP連接的管道上顶燕,從服務(wù)器進(jìn)程向客戶進(jìn)程正在發(fā)送大量的數(shù)據(jù),而客戶進(jìn)程同時(shí)在向服務(wù)器進(jìn)程傳輸中斷字符冈爹。而我們的本意是要中斷字符盡快終止某個(gè)進(jìn)程涌攻,使屏幕上不再有任何響應(yīng)輸出。
在流量控制和中斷鍵這兩種情況中频伤,流量控制機(jī)制很少終止客戶進(jìn)程到服務(wù)器進(jìn)程的數(shù)據(jù)流恳谎。這個(gè)方向僅僅包含我們鍵入的字符。所以對(duì)于從客戶輸出到服務(wù)器的特殊輸入字符(Control_S和中斷字符)不需要采用TCP的緊急方式(urgent mode)。
26.2.4 窗口大小的改變
如果是窗口風(fēng)格的顯示方式因痛,當(dāng)應(yīng)用程序在運(yùn)行的時(shí)候婚苹,我們還可以動(dòng)態(tài)地改變窗口的大小。一些應(yīng)用程序(典型的如那些操作整個(gè)窗口的應(yīng)用程序鸵膏,如全屏編輯器)需要知道窗口大小的變化膊升。目前大多數(shù)Unix系統(tǒng)提供這種功能,可以告訴應(yīng)用程序關(guān)于窗口大小的變化谭企。
對(duì)于遠(yuǎn)程登錄這種情況廓译,窗口大小的變化發(fā)生在客戶端,而運(yùn)行在服務(wù)器端的應(yīng)用程序需要知道窗口大小變化债查。所以Rlogin的客戶需要采用某些方法來通知服務(wù)器窗口大小變化的情況以及新窗口的大小非区。
26.2.5 服務(wù)器到客戶的命令
現(xiàn)在我們介紹通過TCP連接,Rlogin服務(wù)器進(jìn)程可以發(fā)送給客戶進(jìn)程的4條命令盹廷。問題是只有一條TCP連接可供使用,所以服務(wù)器進(jìn)程必須給這些命令字節(jié)做標(biāo)記俄占,使得客戶進(jìn)程可以從數(shù)據(jù)流中識(shí)別出這些是命令管怠,而不是顯示在終端上。所以我們將使用TCP的緊急方式(在20.8節(jié)中曾經(jīng)介紹)颠放。
當(dāng)服務(wù)器要給客戶發(fā)送命令時(shí)排惨,服務(wù)器就進(jìn)入緊急方式,并且把命令放在緊急數(shù)據(jù)的最后一個(gè)字節(jié)中碰凶。當(dāng)客戶進(jìn)程收到這個(gè)緊急方式通知時(shí)暮芭,它從連接上讀取數(shù)據(jù)并且保存起來,直到讀到命令字節(jié)(即緊急數(shù)據(jù)的最后一個(gè)字節(jié))欲低。這時(shí)候客戶進(jìn)程根據(jù)讀到的命令辕宏,再?zèng)Q定對(duì)于所讀到并保存起來的數(shù)據(jù)是顯示在終端上還是丟棄它。圖26-4介紹了這4個(gè)命令砾莱。
采用TCP緊急方式發(fā)送這些命令的一個(gè)原因是第一個(gè)命令(“清倉(cāng)輸出(flush output)”)需要立即發(fā)送給客戶瑞筐,即使服務(wù)器到客戶的數(shù)據(jù)流被窗口流量控制所終止。這種情況下腊瑟,即服務(wù)器到客戶的輸出被流量控制所終止的情況是經(jīng)常發(fā)生的聚假,這是因?yàn)檫\(yùn)行在服務(wù)器的進(jìn)程的輸出速率通常大于客戶終端的顯示速率。另一方面闰非,客戶到服務(wù)器的數(shù)據(jù)流很少被流量控制所終止膘格,因?yàn)檫@個(gè)方向的數(shù)據(jù)流僅僅包含用戶所鍵入的字符。
回憶一下圖20-14中的例子财松,在那里我們介紹了即使窗口大小是0時(shí)瘪贱,緊急通知通過網(wǎng)絡(luò)進(jìn)行傳輸?shù)那闆r(在下節(jié)中纱控,我們還將介紹一個(gè)類似的例子)。其他的3個(gè)命令實(shí)時(shí)性并不特別強(qiáng)菜秦,但為了簡(jiǎn)單起見甜害,也采用了和第一個(gè)命令相同的技術(shù)。
26.2.6 客戶到服務(wù)器的命令
對(duì)于客戶到服務(wù)器的命令球昨,只定義了一條命令尔店,那就是:將當(dāng)前窗口大小發(fā)送給服務(wù)器。當(dāng)客戶的窗口大小發(fā)生變化時(shí)褪尝,客戶并不立即向服務(wù)器報(bào)告闹获,除非收到了服務(wù)器發(fā)來的0x80命令(圖26-4中有介紹)。
同樣河哑,由于只存在一條TCP連接,客戶必須對(duì)在連接上傳輸?shù)脑撁钭止?jié)進(jìn)行標(biāo)注龟虎,使得服務(wù)器可以從數(shù)據(jù)流中識(shí)別出命令璃谨,而不是把它發(fā)送到上層的應(yīng)用程序中去。處理的方法就是在兩個(gè)字節(jié)的0xff后面緊跟著發(fā)送兩個(gè)特殊的標(biāo)志字節(jié)鲤妥。
對(duì)于窗口大小命令佳吞,兩個(gè)標(biāo)志字節(jié)是ASCII碼的字符‘s’。之后是4個(gè)16 bit長(zhǎng)的數(shù)據(jù)(按網(wǎng)絡(luò)字節(jié)順序)棉安,分別是:行數(shù)(例如底扳,25),每列的字符數(shù)(例如贡耽,80)衷模,X方向的像素?cái)?shù)量,Y方向的像素?cái)?shù)量蒲赂。通常情況下阱冶,后兩個(gè)16bit是0,因?yàn)樵赗login服務(wù)器進(jìn)程調(diào)用的應(yīng)用程序中滥嘴,通常是以字符為單位來度量屏幕的木蹬,而不是像素點(diǎn)。
上面我們介紹的從客戶進(jìn)程到服務(wù)器進(jìn)程的命令采用帶內(nèi)信令(in-band signaling)若皱,這是因?yàn)槊钭止?jié)和其他的普通數(shù)據(jù)一起傳輸镊叁。選擇0xff字節(jié)來表示這個(gè)帶內(nèi)信令的原因是:一般用戶的操作不會(huì)產(chǎn)生0xff這個(gè)字節(jié)。所以說Rlogin是不完備的走触,如果我們采用某種方法晦譬,使得通過鍵盤就可以產(chǎn)生兩個(gè)連續(xù)的0xff字節(jié),而且正好在這之前是兩個(gè)ASCII的‘s’字符饺汹,那么下面的8個(gè)字節(jié)就會(huì)被誤認(rèn)為是窗口大小了蛔添。
圖26-4中介紹的是從服務(wù)器到客戶的Rlogin命令,由于大多數(shù)的API采用的技術(shù)叫做“帶外數(shù)據(jù)(out-of-band data)”,所以我們就稱它為帶外信令(out-of-band signaling)迎瞧。但是回憶一下在20.8節(jié)中對(duì)TCP緊急方式的討論夸溶,在那里我們說緊急方式數(shù)據(jù)不是帶外數(shù)據(jù),命令字節(jié)是按照普通數(shù)據(jù)流進(jìn)行傳輸?shù)男坠瑁厥庵幨遣捎昧司o急指針缝裁。
既然帶內(nèi)信令被用來傳輸從客戶到服務(wù)器的命令,那么服務(wù)器進(jìn)程必須檢查從客戶進(jìn)程收到的每個(gè)字節(jié)足绅,看看是否有兩個(gè)連續(xù)的0xff字節(jié)捷绑。但是對(duì)于采用帶外信令的、從服務(wù)器傳輸?shù)降娇蛻舻拿钋饴瑁蛻暨M(jìn)程不需要檢查收到的每個(gè)字節(jié)粹污,除非服務(wù)器進(jìn)程進(jìn)入了緊急方式。即使在緊急方式下首量,客戶進(jìn)程也僅僅需要留意緊急指針?biāo)赶虻淖止?jié)壮吩。而且由于從客戶進(jìn)程到服務(wù)器的數(shù)據(jù)流量和相反方向的數(shù)據(jù)流量之比是1:20,這就暗示帶內(nèi)信令適合于數(shù)據(jù)量比較小的情況(從客戶到服務(wù)器)加缘,而帶外信令適合于數(shù)據(jù)量比較大的情況(從服務(wù)器到客戶)鸭叙。
26.2.7 客戶的轉(zhuǎn)義符
通常情況下,我們向Rlogin客戶進(jìn)程鍵入的信息將傳輸?shù)椒?wù)器進(jìn)程拣宏。但是有些時(shí)候沈贝,我們并不需要把鍵入的信息傳輸?shù)椒?wù)器,而是要和Rlogin客戶進(jìn)程直接通信勋乾。方法是在一行的開頭鍵入代字符(tilde)“~”宋下,緊跟著是下列4個(gè)字符之一:
1:以一個(gè)句號(hào)結(jié)束客戶進(jìn)程。
2:以文件結(jié)束符(通常是Control_D)結(jié)束客戶進(jìn)程市俊。
3:以任務(wù)控制掛起符(通常是Control_Z)掛起客戶進(jìn)程杨凑。
4:以任務(wù)控制延遲掛起符(通常是Control_Y)來掛起僅僅是客戶進(jìn)程的輸入。這時(shí)摆昧,不管客戶運(yùn)行什么程序撩满,鍵入的任何信息將由該程序進(jìn)行解釋,但是從服務(wù)器發(fā)送到客戶的信息還是輸出到終端上绅你。這非常適合當(dāng)我們需要在服務(wù)器上運(yùn)行一個(gè)長(zhǎng)時(shí)間程序的場(chǎng)合伺帘,我們既想知道該程序的輸出結(jié)果,同時(shí)還想在客戶上運(yùn)行其他程序忌锯。
只有當(dāng)客戶進(jìn)程的Unix系統(tǒng)支持任務(wù)控制時(shí)伪嫁,后兩個(gè)命令才有效。
26.3 Rlogin的例子
在這里舉兩個(gè)例子:第一個(gè)是當(dāng)Rlogin會(huì)話建立的時(shí)候偶垮,客戶和服務(wù)器的協(xié)議交互张咳;從第二個(gè)例子可以看到谬盐,當(dāng)用戶鍵入中斷鍵以取消正在服務(wù)器運(yùn)行的程序時(shí)恬试,服務(wù)器將產(chǎn)生很多輸出衰腌。在圖19-2中抡草,我們給出了通常情況下,Rlogin會(huì)話上的數(shù)據(jù)流交互情況龙助。
26.3.1 初始的客戶-服務(wù)器協(xié)議
圖26-5顯示的是從主機(jī)bsdi到服務(wù)器svr4的Rlogin建立一個(gè)連接時(shí)的時(shí)間系列(在圖中砰奕,去掉了通常的TCP連接的建立過程,窗口通告以及服務(wù)類型信息)提鸟。
上節(jié)介紹的協(xié)議對(duì)應(yīng)圖中的報(bào)文段1~9军援。客戶發(fā)送一個(gè)字節(jié)的0(報(bào)文段1)之后發(fā)送3個(gè)字符串(報(bào)文段3)称勋。在本例中胸哥,這3個(gè)字符串分別是:rstevens(客戶的登錄名)、rstevens(服務(wù)器的登錄名)和ibmpc3/9600(終端類型和速率)赡鲜。當(dāng)服務(wù)器確認(rèn)了這些信息后回送一個(gè)字節(jié)的0(報(bào)文段5)烘嘱。
然后服務(wù)器發(fā)送窗口請(qǐng)求命令(報(bào)文段7)。這是采用TCP緊急方式發(fā)送的蝗蛙,我們又一次看到一個(gè)實(shí)現(xiàn)(SVR4)采用較老的但更普通的解釋,即緊急指針指明的序號(hào)是緊急數(shù)據(jù)的最后一個(gè)字節(jié)加1醉鳖〖窆瑁客戶回送12字節(jié)的數(shù)據(jù):2字節(jié)的0xff,2字節(jié)的‘s’盗棵,4個(gè)16 bit長(zhǎng)度的窗口數(shù)據(jù)壮韭。
下面的4個(gè)報(bào)文段(10,12,14和16)是由服務(wù)器發(fā)送的,是從服務(wù)器操作系統(tǒng)的問候(greeting)纹因。之后報(bào)文段18是一個(gè)7字節(jié)長(zhǎng)度的外殼進(jìn)程提示符“svr4%”喷屋。
客戶輸入的信息如圖19-2所示,每次發(fā)送一個(gè)字節(jié)瞭恰⊥筒埽客戶和服務(wù)器都可以主動(dòng)中斷該連接。如果我們輸入一個(gè)命令惊畏,讓服務(wù)器的外殼程序終止運(yùn)行恶耽,那么服務(wù)器將中斷該連接。如果我們給Rlogin客戶鍵入一個(gè)轉(zhuǎn)移符(通常是一個(gè)“~”)颜启,緊跟著一個(gè)句點(diǎn)或者是一個(gè)文件結(jié)束符號(hào)偷俭,那么客戶將主動(dòng)關(guān)閉該連接。
圖26-5中缰盏,客戶進(jìn)程的端口號(hào)是1023涌萤,這是由IANA分配的(在1.9節(jié)中介紹)淹遵。Rlogin協(xié)議要求客戶進(jìn)程用小于1024的端口號(hào),術(shù)語(yǔ)叫做保留端口负溪。在Unix系統(tǒng)中透揣,客戶進(jìn)程一般不能使用保留端口號(hào),除非客戶進(jìn)程具有超級(jí)用戶權(quán)限笙以。這是客戶進(jìn)程和服務(wù)器進(jìn)程相互鑒別的一部分淌实,這種鑒別可以使得用戶不需要口令而可以登錄。[Stevens 1990]詳細(xì)討論了客戶進(jìn)程和服務(wù)器進(jìn)程相互鑒別的過程和有關(guān)保留端口號(hào)的問題猖腕。
26.3.2 客戶中斷鍵
讓我們看一下另外一個(gè)例子拆祈,這個(gè)例子涉及到TCP的緊急方式。當(dāng)數(shù)據(jù)流已經(jīng)終止時(shí)倘感,我們鍵入中斷鍵放坏。這個(gè)例子要用到前面講到的很多TCP算法如:緊急方式、糊涂窗口避免技術(shù)老玛、窗口流量控制和堅(jiān)持計(jì)時(shí)器淤年。在主機(jī)sun上運(yùn)行客戶進(jìn)程。我們登錄到主機(jī)bsdi蜡豹,向終端輸出一個(gè)大文本文件麸粮,然后鍵入Control_S中斷輸出。當(dāng)輸出停止時(shí)镜廉,我們鍵入中斷鍵(DELETE)以異常方式中止該進(jìn)程弄诲。
下面這些要點(diǎn)是關(guān)于客戶、服務(wù)器和連接的狀態(tài)的概述:
1:鍵入Control_S以停止終端的輸出娇唯。
2:用戶終端的輸出緩存很快被填滿齐遵,所以Rlogin的客戶向終端的寫操作被阻塞。
3:此時(shí)客戶也不能從網(wǎng)絡(luò)連接上讀取數(shù)據(jù)塔插,所以客戶的TCP接收緩存也將被填滿梗摇。
4:當(dāng)接收緩存已滿時(shí),客戶進(jìn)程的TCP會(huì)向服務(wù)器進(jìn)程的TCP通告現(xiàn)在的接收窗口是0想许。
5:當(dāng)服務(wù)器收到客戶的窗口為0時(shí)伶授,將停止向客戶發(fā)送數(shù)據(jù),這樣伸刃,服務(wù)器的發(fā)送緩存也將被填滿谎砾。
6:由于發(fā)送緩存已滿,所以Rlogin服務(wù)器進(jìn)程將停止捧颅。這樣景图,Rlogin服務(wù)器將不能從服務(wù)器運(yùn)行的應(yīng)用程序(cat)處讀取數(shù)據(jù)。
7:當(dāng)cat程序的輸出緩存也被填滿時(shí)碉哑,cat也將停止挚币。
8:然后我們用中斷鍵來終止服務(wù)器上的cat程序亮蒋。這個(gè)命令從客戶的TCP傳輸?shù)椒?wù)器的TCP,這是因?yàn)樵摲较虻臄?shù)據(jù)傳輸沒有被流量控制所終止妆毕。
9:cat應(yīng)用程序收到中斷命令并且終止慎玖。這使得它的輸出緩存(也就是Rlogin服務(wù)器進(jìn)程讀取數(shù)據(jù)的地方)被清空,這將喚醒Rlogin服務(wù)器進(jìn)程笛粘。然后Rlogin服務(wù)器進(jìn)程進(jìn)入緊急方式趁怔,向客戶進(jìn)程發(fā)送“清倉(cāng)輸出”命令(0x02)。
圖26-6概括了從服務(wù)器到客戶的數(shù)據(jù)流(圖中的序號(hào)就是下面將介紹的圖中的時(shí)間系列)薪前。
發(fā)送緩存的陰影部分是4096字節(jié)的緩存中沒有被使用的部分。圖26-7是該例子的時(shí)間系列示括。
在報(bào)文段1~3铺浇,服務(wù)器進(jìn)程向客戶進(jìn)程發(fā)送滿長(zhǎng)度(即1024字節(jié))的TCP報(bào)文段。由于此時(shí)客戶進(jìn)程不能向終端寫信息垛膝,客戶進(jìn)程也不能從網(wǎng)絡(luò)上讀數(shù)據(jù)鳍侣,所以在報(bào)文段4中,客戶進(jìn)程向服務(wù)器進(jìn)程發(fā)送ACK確認(rèn)時(shí)吼拥,告訴服務(wù)器進(jìn)程此時(shí)接收窗口是1024個(gè)字節(jié)倚聚。在報(bào)文段5中,服務(wù)器進(jìn)程發(fā)送的數(shù)據(jù)長(zhǎng)度就不再是滿長(zhǎng)度的了凿可。同樣秉沼,報(bào)文段6中客戶進(jìn)程的確認(rèn)信號(hào)所帶的接收窗口大小是此時(shí)接收緩存的空余字節(jié)長(zhǎng)度。那么在報(bào)文段5中矿酵,客戶進(jìn)程ACK信號(hào)中為什么接收窗口大小是349而不是0呢?這是因?yàn)槿绻l(fā)送的是0(糊涂窗口避免技術(shù))矗积,那么窗口指針將右邊界移動(dòng)到了左邊界全肮,而這是絕對(duì)不能發(fā)生的(見20.3節(jié))。當(dāng)服務(wù)器進(jìn)程收到報(bào)文段6的ACK信號(hào)后棘捣,它就不能再發(fā)送全長(zhǎng)的數(shù)據(jù)報(bào)了辜腺,這時(shí)候它就采用糊涂窗口癥避免技術(shù),不發(fā)送任何東西乍恐,同時(shí)置一個(gè)5秒的堅(jiān)持計(jì)時(shí)器评疗。當(dāng)計(jì)時(shí)器超時(shí),服務(wù)器進(jìn)程就發(fā)送一個(gè)349字節(jié)大小的數(shù)據(jù)(如報(bào)文段7)茵烈。由于此時(shí)客戶進(jìn)程依然不能輸出接收緩存的信息百匆,所以接收緩存將被填滿,客戶進(jìn)程將發(fā)送ACK信號(hào)呜投,此時(shí)接收窗口大小為0(如報(bào)文段8)加匈。
這時(shí)候我們鍵入中斷鍵并且以報(bào)文段9顯示的那樣傳輸存璃。此時(shí)的接收窗口大小依然為0。當(dāng)服務(wù)器進(jìn)程接收到該中斷鍵后雕拼,服務(wù)器進(jìn)程把它發(fā)送給應(yīng)用程序(cat)纵东,應(yīng)用程序就終止。由于應(yīng)用程序被終端中斷鍵所終止啥寇,應(yīng)用程序就清空它的輸出緩存偎球。服務(wù)器進(jìn)程發(fā)現(xiàn)該變化后就通過TCP緊急方式向客戶進(jìn)程發(fā)送“清倉(cāng)輸出”命令,這如報(bào)文段10所示辑甜。注意命令字節(jié)0x02放在第30146字節(jié)中(緊急指針減1)衰絮。報(bào)文段10告訴客戶進(jìn)程在命令字節(jié)前還有3419個(gè)字節(jié)(從26727到30145)在服務(wù)器進(jìn)程的發(fā)送緩存中等待發(fā)送。
報(bào)文段10采用緊急通知方式發(fā)送栈戳,包含了服務(wù)器進(jìn)程向客戶進(jìn)程發(fā)送的下一個(gè)字節(jié)(序號(hào)是26727)岂傲。它不包含“清倉(cāng)輸出”命令字節(jié)。記得在22.2節(jié)中曾經(jīng)介紹過子檀,發(fā)送進(jìn)程可以發(fā)送一個(gè)字節(jié)的數(shù)據(jù)來試探對(duì)方的接收窗口是否關(guān)閉镊掖。報(bào)文段10就是采用了這個(gè)原理。然后客戶進(jìn)程TCP就立即發(fā)送如報(bào)文段11所示的數(shù)據(jù)褂痰。雖然此時(shí)接收窗口還是0亩进,但是在客戶進(jìn)程內(nèi)部,由于客戶進(jìn)程的TCP收到了對(duì)方的緊急通知缩歪,它把該通知告訴客戶進(jìn)程归薛,客戶進(jìn)程就知道服務(wù)器進(jìn)程已經(jīng)進(jìn)入了緊急方式了。
當(dāng)Rlogin客戶進(jìn)程從它的TCP收到了緊急通知匪蝙,并且客戶進(jìn)程開始讀取已經(jīng)在輸入緩存中等待被讀取的數(shù)據(jù)時(shí)主籍,接收窗口就會(huì)重新打開(報(bào)文段13)。然后服務(wù)器進(jìn)程就開始正常發(fā)送數(shù)據(jù)(報(bào)文段14,15,17和18)逛球。注意報(bào)文段18的數(shù)據(jù)報(bào)中包含緊急數(shù)據(jù)的最后一個(gè)字節(jié)的數(shù)據(jù)(序號(hào)30146)千元,該字節(jié)包含服務(wù)器進(jìn)程發(fā)送給客戶進(jìn)程的命令字節(jié)。當(dāng)客戶進(jìn)程收到該命令后颤绕,它就丟棄報(bào)文段14幸海、15、17和18所收到的數(shù)據(jù)奥务,并且清空終端的輸出緩存物独。在報(bào)文段19中的下兩個(gè)字節(jié)是中斷鍵的回顯“^?”。最后一個(gè)報(bào)文段(21)包含了客戶進(jìn)程的外殼提示符氯葬。
這個(gè)例子描述了當(dāng)用戶鍵入中斷鍵后挡篓,連接的雙方數(shù)據(jù)如何被存儲(chǔ)的情況。如果這些動(dòng)作僅僅丟棄在服務(wù)器的3419個(gè)字節(jié)數(shù)據(jù)帚称,而不丟棄已經(jīng)在客戶的4096個(gè)字節(jié)的數(shù)據(jù)瞻凤,那么這些已經(jīng)在客戶的終端輸出緩存中的4096字節(jié)數(shù)據(jù)將輸出到終端上憨攒。
26.4 Telnet協(xié)議
Te lnet協(xié)議可以工作在任何主機(jī)(例如,任何操作系統(tǒng))或任何終端之間阀参。RFC 854 [Postel 和Reynolds 1983a]定義了該協(xié)議的規(guī)范肝集,其中還定義了一種通用字符終端叫做網(wǎng)絡(luò)虛擬終端NVT(Network Virtual Terminal)。NVT是虛擬設(shè)備蛛壳,連接的雙方杏瞻,即客戶機(jī)和服務(wù)器,都必須把它們的物理終端和NVT進(jìn)行相互轉(zhuǎn)換衙荐。也就是說捞挥,不管客戶進(jìn)程終端是什么類型,操作系統(tǒng)必須把它轉(zhuǎn)換為NVT格式忧吟。同時(shí)砌函,不管服務(wù)器進(jìn)程的終端是什么類型,操作系統(tǒng)必須能夠把NVT格式轉(zhuǎn)換為終端所能夠支持的格式溜族。
NVT是帶有鍵盤和打印機(jī)的字符設(shè)備讹俊。用戶擊鍵產(chǎn)生的數(shù)據(jù)被發(fā)送到服務(wù)器進(jìn)程,服務(wù)器進(jìn)程回送的響應(yīng)則輸出到打印機(jī)上煌抒。默認(rèn)情況下仍劈,用戶擊鍵產(chǎn)生的數(shù)據(jù)是發(fā)送到打印機(jī)上的,但是我們可以看到這個(gè)選項(xiàng)是可以改變的寡壮。
26.4.1 NVT ASCII
術(shù)語(yǔ)NVT ASCII代表7比特的ASCII字符集贩疙,網(wǎng)間網(wǎng)協(xié)議族都使用NVT ASCII。每個(gè)7比特的字符都以8比特格式發(fā)送况既,最高位比特為0这溅。
行結(jié)束符以兩個(gè)字符CR(回車)和緊接著的LF(換行)這樣的序列表示。以\r\n來表示棒仍。單獨(dú)的一個(gè)CR也是以兩個(gè)字符序列來表示芍躏,它們是CR和緊接著的NUL(字節(jié)0),以\r\0表示降狠。
在下面的章節(jié)中可以看到,F(xiàn)TP,SMTP,Finger和Whois協(xié)議都以NVT ASCII來描述客戶命令和服務(wù)器的響應(yīng)庇楞。
26.4.2 Telnet命令
Telnet通信的兩個(gè)方向都采用帶內(nèi)信令方式榜配。字節(jié)0xff(十進(jìn)制的255)叫做IAC(interpret as command,意思是“作為命令來解釋”)吕晌。該字節(jié)后面的一個(gè)字節(jié)才是命令字節(jié)蛋褥。如果要發(fā)送數(shù)據(jù)255,就必須發(fā)送兩個(gè)連續(xù)的字節(jié)255(在前面一節(jié)中我們講到數(shù)據(jù)流是NVTASCII睛驳,它們都是7bit的格式烙心,這就暗示著255這個(gè)數(shù)據(jù)字節(jié)不能在Telnet上傳輸膜廊。其實(shí)在Telnet中有一個(gè)二進(jìn)制選項(xiàng),在RFC 856 [Postel和Reynolds 1983b]中有定義淫茵,關(guān)于這點(diǎn)我們沒有討論爪瓜,該選項(xiàng)允許數(shù)據(jù)以8bit進(jìn)行傳輸)。圖26-8列出了所有的Telnet命令匙瘪。
由于這些命令中很多命令很少用到铆铆,所以對(duì)于一些重要的命令,如果在下面章節(jié)的例子或敘述中遇到丹喻,我們?cè)僮鼋忉尅?/p>
26.4.3 選項(xiàng)協(xié)商
雖然我們可以認(rèn)為Telnet連接的雙方都是NVT薄货,但是實(shí)際上Telnet連接雙方首先進(jìn)行交互的信息是選項(xiàng)協(xié)商數(shù)據(jù)。選項(xiàng)協(xié)商是對(duì)稱的碍论,也就是說任何一方都可以主動(dòng)發(fā)送選項(xiàng)協(xié)商請(qǐng)求給對(duì)方谅猾。
對(duì)于任何給定的選項(xiàng),連接的任何一方都可以發(fā)送下面4種請(qǐng)求的任意一個(gè)請(qǐng)求鳍悠。
1:WILL:發(fā)送方本身將激活(enable)選項(xiàng)税娜。
2:DO:發(fā)送方想叫接收端激活選項(xiàng)。
3:WONT:發(fā)送方本身想禁止選項(xiàng)贼涩。
4:DON’T:發(fā)送方想讓接收端去禁止選項(xiàng)巧涧。
由于Telnet規(guī)則規(guī)定,對(duì)于激活選項(xiàng)請(qǐng)求(如1和2)遥倦,有權(quán)同意或者不同意谤绳。而對(duì)于使選項(xiàng)失效請(qǐng)求(如3和4),必須同意袒哥。這樣缩筛,4種請(qǐng)求就會(huì)組合出6種情況,如圖26-9所示堡称。
選項(xiàng)協(xié)商需要3個(gè)字節(jié):一個(gè)IAC字節(jié)瞎抛,接著一個(gè)字節(jié)是WILL,DO,WONT和DONT這四者之一,最后一個(gè)ID字節(jié)指明激活或禁止選項(xiàng)∪唇簦現(xiàn)在桐臊,有40多個(gè)選項(xiàng)是可以協(xié)商的。Assigned Number RFC文檔中指明選項(xiàng)字節(jié)的值晓殊,并且一些相關(guān)的RFC文檔描述了這些選項(xiàng)断凶。圖26-10顯示了在本章中會(huì)出現(xiàn)的選項(xiàng)代碼。
Telnet的選項(xiàng)協(xié)商機(jī)制和Telnet協(xié)議的大部分內(nèi)容一樣巫俺,是對(duì)稱的认烁。連接的雙方都可以發(fā)起選項(xiàng)協(xié)商請(qǐng)求。但我們知道,遠(yuǎn)程登錄不是對(duì)稱的應(yīng)用却嗡〔芭妫客戶進(jìn)程完成某些任務(wù),而服務(wù)器進(jìn)程則完成其他一些任務(wù)窗价。下面我們將看到如庭,某些Telnet選項(xiàng)僅僅適合于客戶進(jìn)程(例如要求激活行模式方式),某些選項(xiàng)則僅僅適合于服務(wù)器進(jìn)程舌镶。
26.4.4 子選項(xiàng)協(xié)商
有些選項(xiàng)不是僅僅用“激活”或“禁止”就能夠表達(dá)的柱彻。指定終端類型就是一個(gè)例子,客戶進(jìn)程必須發(fā)送用一個(gè)ASCII字符串來表示終端類型餐胀。為了處理這種選項(xiàng)哟楷,我們必須定義子選項(xiàng)協(xié)商機(jī)制。
在RFC1091[VanBokkelen 1989]中定義了如何表示終端類型這樣的子選項(xiàng)協(xié)商機(jī)制否灾。首先連接的某一方(通常是客戶進(jìn)程)發(fā)送3個(gè)字節(jié)的字符序列來請(qǐng)求激活該選項(xiàng)卖擅。
<IAC,WILL,24>
這里的24(十進(jìn)制)是終端類型選項(xiàng)的ID號(hào)。如果收端(通常是服務(wù)器進(jìn)程)同意墨技,那么響應(yīng)數(shù)據(jù)是:
<IAC,SB,24,1,IAC,SE>
該字符串詢問客戶進(jìn)程的終端類型惩阶。其中SB是子選項(xiàng)協(xié)商的起始命令標(biāo)志。下一個(gè)字節(jié)的“24”代表這是終端類型選項(xiàng)的子選項(xiàng)(通常SB后面的選項(xiàng)值就是子選項(xiàng)所要提交的內(nèi)容)扣汪。下一個(gè)字節(jié)的“1”表示“發(fā)送你的終端類型”断楷。子選項(xiàng)協(xié)商的結(jié)束命令標(biāo)志也是IAC,就像SB是起始命令標(biāo)志一樣崭别。如果終端類型是ibmpc冬筒,客戶進(jìn)程的響應(yīng)命令將是:
<IAC,SB,24,0‘I’,‘B’,‘M’,‘P’,‘C’,IAC,SE>
第4個(gè)字節(jié)“0”代表“我的終端類型是”(在Assigned Numbers RFC文檔中有正式的關(guān)于終端類型的數(shù)值定義,但是最起碼在Unix系統(tǒng)之間茅主,終端類型可以用任何對(duì)方可理解的數(shù)據(jù)進(jìn)行表示舞痰。只要這些數(shù)據(jù)在termcap或terminfo數(shù)據(jù)庫(kù)中有定義)。在Te lnet子選項(xiàng)協(xié)商過程中诀姚,終端類型用大寫表示响牛,當(dāng)服務(wù)器收到該字符串后會(huì)自動(dòng)轉(zhuǎn)換為小寫字符。
26.4.5 半雙工赫段、一次一字符呀打、一次一行或行方式
對(duì)于大多數(shù)Telnet的服務(wù)器進(jìn)程和客戶進(jìn)程,共有4種操作方式糯笙。
- 半雙工
這是Telnet的默認(rèn)方式贬丛,但現(xiàn)在卻很少使用。NVT默認(rèn)是一個(gè)半雙工設(shè)備炬丸,在接收用戶輸入之前,它必須從服務(wù)器進(jìn)程獲得GO AHEAD(GA)命令。用戶的輸入在本地回顯稠炬,方向是從NVT鍵盤到NVT打印機(jī)焕阿,所以客戶進(jìn)程到服務(wù)器進(jìn)程只能發(fā)送整行的數(shù)據(jù)。
雖然該方式適用于所有類型的終端設(shè)備首启,但是它不能充分發(fā)揮目前大量使用的支持全雙工通信的終端功能暮屡。RFC 857 [Postel 和Reynolds 1983c]定義了ECHO選項(xiàng),RFC 858 [Postel和Reynolds 1983d]定義了SUPPRESS GO AHEAD(抑制繼續(xù)進(jìn)行)選項(xiàng)毅桃。如果聯(lián)合使用這兩個(gè)選項(xiàng)褒纲,就可以支持下面將討論的方式:帶遠(yuǎn)程回顯的一次一個(gè)字符的方式。
- 一次一個(gè)字符方式
這和前面的Rlogin工作方式類似钥飞。我們所鍵入的每個(gè)字符都單獨(dú)發(fā)送到服務(wù)器進(jìn)程莺掠。服務(wù)器進(jìn)程回顯大多數(shù)的字符,除非服務(wù)器進(jìn)程端的應(yīng)用程序去掉了回顯功能读宙。
該方式的缺點(diǎn)也是顯而易見的彻秆。當(dāng)網(wǎng)絡(luò)速度很慢,而且網(wǎng)絡(luò)流量比較大的時(shí)候结闸,那么回顯的速度也會(huì)很慢唇兑。雖然如此,但目前大多數(shù)Te lnet實(shí)現(xiàn)都把這種方式作為默認(rèn)方式桦锄。
我們將看到扎附,如果要進(jìn)入這種方式,只要激活服務(wù)器進(jìn)程的SUPPRESS GO AHEAD選項(xiàng)即可结耀。這可以通過由客戶進(jìn)程發(fā)送DO SUPPRESS GO AHEAD(請(qǐng)求激活服務(wù)器進(jìn)程的選項(xiàng))請(qǐng)求完成留夜,也可以通過服務(wù)器進(jìn)程給客戶進(jìn)程發(fā)送WILL SUPPRESS GO AHEAD(服務(wù)器進(jìn)程激活選項(xiàng))請(qǐng)求來完成。服務(wù)器進(jìn)程通常還會(huì)跟著發(fā)送WILL ECHO饼记,以使回顯功能有效香伴。
- 一次一行方式
該方式通常叫做準(zhǔn)行方式(kludge line mode),該方式的實(shí)現(xiàn)是遵照RFC 858的具则。該RFC規(guī)定:如果要實(shí)現(xiàn)帶遠(yuǎn)程回顯的一次一個(gè)字符方式即纲,ECHO選項(xiàng)和SUPPRESS GO AHEAD選項(xiàng)必須同時(shí)有效。準(zhǔn)行方式采用這種方式來表示當(dāng)兩個(gè)選項(xiàng)的其中之一無效時(shí)博肋,Telnet就是工作在一次一行方式低斋。在下節(jié)中我們將介紹一個(gè)例子,可以看到如何協(xié)商進(jìn)入該方式匪凡,并且當(dāng)程序需要接收每個(gè)擊鍵時(shí)如何使該方式失效膊畴。
- 行方式
我們用這個(gè)術(shù)語(yǔ)代表實(shí)行方式選項(xiàng),這是在RFC 1184 [Borman 1990]中定義的病游。這個(gè)選項(xiàng)也是通過客戶進(jìn)程和服務(wù)器進(jìn)程進(jìn)行協(xié)商而確定的唇跨,它糾正了準(zhǔn)行方式的所有缺陷稠通。目前比較新的Telnet實(shí)現(xiàn)支持這種方式。
圖26-11是不同的Telnet客戶進(jìn)程和服務(wù)器進(jìn)程之間默認(rèn)的操作方式买猖「拈伲“char”表示一次一個(gè)字符方式,“kludge”表示準(zhǔn)行方式玉控,“l(fā)inemode”表示如RFC 1184定義的實(shí)行方式飞主。
從圖中可以看出,只有當(dāng)客戶進(jìn)程和服務(wù)器進(jìn)程都是BSD/386或4.4BSD的時(shí)候才支持實(shí)行方式高诺。當(dāng)服務(wù)器進(jìn)程的操作系統(tǒng)是這兩者之一時(shí)碌识,如果客戶進(jìn)程不支持實(shí)行方式,才會(huì)協(xié)商進(jìn)入準(zhǔn)行方式虱而。從圖中還可以看出筏餐,其實(shí)任何類型的客戶進(jìn)程和服務(wù)器進(jìn)程都支持準(zhǔn)行方式,但是一般都不把它作為默認(rèn)方式薛窥,除非服務(wù)器進(jìn)程指定胖烛。
26.4.6 同步信號(hào)
Telnet以Data Mark命令(即圖26-8中的DM)作為同步信號(hào),該同步信號(hào)是以TCP緊急數(shù)據(jù)形式發(fā)送的诅迷。DM命令是隨數(shù)據(jù)流傳輸?shù)耐綐?biāo)志佩番,它告訴收端回到正常的處理過程上來。Telnet的雙方都可以發(fā)送該命令罢杉。
當(dāng)一端收到對(duì)方已經(jīng)進(jìn)入了緊急方式的通知后趟畏,它將開始讀數(shù)據(jù)流,一邊讀一邊丟棄所讀的數(shù)據(jù)滩租,直到讀到Telnet命令為止赋秀。緊急數(shù)據(jù)的最后一個(gè)字節(jié)就是DM字節(jié)。采用TCP緊急方式的原因就是:即使TCP數(shù)據(jù)流已經(jīng)被TCP流量控制所終止律想,Telnet命令也可以在連接上傳輸猎莲。
在下節(jié)中我們將看到Telnet同步信號(hào)的使用情況。
26.4.7 客戶的轉(zhuǎn)義符
和Rlogin的客戶進(jìn)程一樣技即,Telnet客戶進(jìn)程也可以使用戶直接和客戶進(jìn)程進(jìn)行交互著洼,而不是被發(fā)送到服務(wù)器進(jìn)程。通扯穑客戶的轉(zhuǎn)義字符是Control_](control鍵和右中括號(hào)鍵身笤,通常以“^]”表示)。這使得客戶進(jìn)程顯示它的提示符葵陵,通常是“telnet>”液荸。這時(shí)候有很多命令可供用戶選擇,以改變連接的特性或打印某些信息脱篙。大多數(shù)的Unix客戶進(jìn)程提供“help”命令娇钱,該命令將顯示所有可用的命令伤柄。
在下節(jié)中我們將看到客戶進(jìn)程轉(zhuǎn)義的例子,以及此時(shí)可以輸入的命令文搂。
26.5 Telnet舉例
在這里我們將介紹在三種不同的操作方式下Telnet選項(xiàng)協(xié)商的情況响迂。這些方式包括:?jiǎn)巫址绞健?shí)行方式和準(zhǔn)行方式细疚。同樣我們還將討論當(dāng)用戶在服務(wù)器端按了中斷鍵退出了一個(gè)正在運(yùn)行的進(jìn)程后,系統(tǒng)的運(yùn)行情況川梅。
26.5.1 單字符方式
首先介紹基本的單字符方式疯兼,該方式類似于Rlogin。用戶在終端輸入的每個(gè)字符都將由終端發(fā)送到服務(wù)器進(jìn)程贫途,服務(wù)器進(jìn)程的響應(yīng)也將以字符方式回顯到終端上吧彪。在這里運(yùn)行的是一個(gè)新的客戶進(jìn)程BSD/386,它試圖激活很多新的選項(xiàng)丢早,服務(wù)器進(jìn)程還是運(yùn)行老的SVR4姨裸,我們將看到很多選項(xiàng)被服務(wù)器拒絕。
為了看到服務(wù)器和客戶機(jī)之間選項(xiàng)協(xié)商的內(nèi)容怨酝,我們將激活客戶進(jìn)程的一個(gè)選項(xiàng)來顯示所有的選項(xiàng)協(xié)商傀缩。同樣我們運(yùn)行tcpdump來獲得數(shù)據(jù)報(bào)交換的時(shí)間次序。圖26-12顯示了這個(gè)交互會(huì)話农猬。
在圖中赡艰,我們已經(jīng)對(duì)由SENT或RCVD開頭的選項(xiàng)協(xié)商的每一步都進(jìn)行了標(biāo)注。關(guān)于每一步的解釋如下:
1)客戶發(fā)起SUPPRESS GO AHEAD選項(xiàng)協(xié)商斤葱。由于GO AHEAD命令通常是由服務(wù)器發(fā)送給客戶的慷垮,而且客戶希望服務(wù)器激活該選項(xiàng),因此該選項(xiàng)的請(qǐng)求方式是DO(由于激活這一選項(xiàng)將會(huì)禁止GA命令的發(fā)送揍堕,上述過程很容易讓人混淆)料身。在第10行可以看到服務(wù)器進(jìn)程同意該選項(xiàng)。
2)客戶進(jìn)程要按照在RFC 1091[VanBokkelen 1989]中的定義發(fā)送終端類型衩茸。這對(duì)Unix類型的客戶進(jìn)程來講是很普通的芹血。因?yàn)榭蛻暨M(jìn)程要激活本地的選項(xiàng),所以該選項(xiàng)的請(qǐng)求方式是WILL递瑰。
3)NAWS的意思是“協(xié)商窗口大小”祟牲,它在RFC 1073 [Waitzman]中有定義。如果服務(wù)器進(jìn)程同意該選項(xiàng)(實(shí)際上不同意,見11行),客戶進(jìn)程就要發(fā)送終端窗口的行棵逊、列大小的子選項(xiàng)耕驰。而且只要窗口大小發(fā)生變化,客戶進(jìn)程隨時(shí)都將向服務(wù)器進(jìn)程發(fā)送這一子選項(xiàng)(這和圖26-4中Rlogin的0x80命令類似)籽孙。
4)TSPEED選項(xiàng)允許發(fā)送方(通常是客戶進(jìn)程)發(fā)送它的終端速率亲善,這在RFC 1079 [Hedrick 1988b]中有定義凉袱。如果服務(wù)器進(jìn)程同意(實(shí)際上不同意傲宜,見12行)运杭,客戶進(jìn)程將發(fā)送其發(fā)送速率和接收速率的子選項(xiàng)。
5)LFLOW代表“本地流量控制”函卒,這在RFC 1371 [Hedrick和Borman 1992]中定義辆憔。客戶進(jìn)程給服務(wù)器進(jìn)程發(fā)送該選項(xiàng)报嵌,表示客戶進(jìn)程希望用命令方式激活或禁止流量控制虱咧。如果服務(wù)器進(jìn)程同意(實(shí)際上不同意,見13行)锚国,只要Control_S和Control_Q進(jìn)程需要在客戶進(jìn)程和服務(wù)器進(jìn)程進(jìn)行切換腕巡,客戶進(jìn)程都要向服務(wù)器進(jìn)程發(fā)送子選項(xiàng)(這類似于圖26-4中Rlogin的0x10和0x20命令)。正如在關(guān)于Rlogin的討論中我們所提到的那樣血筑,由客戶進(jìn)程進(jìn)行流量控制的效果比由服務(wù)器進(jìn)程來完成要好绘沉。
6)LINEMODE代表在26.4中所說的實(shí)行方式。所有終端字符的處理由Telnet客戶進(jìn)程完成(例如回格豺总,刪除行等)车伞,然后整行發(fā)送給服務(wù)器進(jìn)程。在本節(jié)后面喻喳,我們將介紹一個(gè)例子帖世。該選項(xiàng)同樣被服務(wù)器進(jìn)程拒絕,如14行所示沸枯。
7)ENVIRON選項(xiàng)允許客戶進(jìn)程把環(huán)境變量發(fā)送給服務(wù)器進(jìn)程日矫,這在RFC 1408 [Borman 1993a]中有定義。這樣就可以把客戶進(jìn)程的用戶環(huán)境變量自動(dòng)傳播到服務(wù)器進(jìn)程绑榴。在15行哪轿,服務(wù)器進(jìn)程拒絕該選項(xiàng)(Unix中的環(huán)境變量通常是大寫字母,緊跟一個(gè)等號(hào)翔怎,然后是一個(gè)字符串值窃诉,當(dāng)然這只是一個(gè)慣例而已)。默認(rèn)情況下赤套,BSD/386 Telnet客戶進(jìn)程發(fā)送兩個(gè)環(huán)境變量:DISPLAY和PRINTER飘痛,前提是這兩個(gè)變量已經(jīng)定義并且有效。Telnet用戶可以定義其他一些要發(fā)送的環(huán)境變量容握。
8)STATUS選項(xiàng)(RFC 859 [Postel 和Reynolds 1983e]中定義)允許連接的一方詢問對(duì)方對(duì)Te lnet選項(xiàng)目前狀態(tài)的理解宣脉。在這個(gè)例子中,客戶進(jìn)程要求對(duì)方激活選項(xiàng)(DO)剔氏。如果服務(wù)器進(jìn)程同意(實(shí)際上不同意塑猖,見16行)竹祷,客戶進(jìn)程就可以要求服務(wù)器進(jìn)程以子選項(xiàng)的形式發(fā)送它的狀態(tài)值。
9)這是服務(wù)器進(jìn)程的第一個(gè)響應(yīng)羊苟。服務(wù)器進(jìn)程同意激活終端類型選項(xiàng)(幾乎所有的Unix類型的服務(wù)器進(jìn)程都支持該選項(xiàng))塑陵。但現(xiàn)在客戶進(jìn)程還不能立即發(fā)送它的終端類型。它必須要等到服務(wù)器進(jìn)程用子選項(xiàng)的形式詢問終端類型的時(shí)候才能夠發(fā)送(17行)蜡励。
10)服務(wù)器進(jìn)程同意抑制發(fā)送GO AHEAD命令令花。
11)服務(wù)器進(jìn)程不同意客戶進(jìn)程發(fā)送它的窗口大小。
12)服務(wù)器進(jìn)程不同意客戶進(jìn)程發(fā)送它的終端速率凉倚。
13)服務(wù)器進(jìn)程不同意客戶進(jìn)程實(shí)施流量控制彭则。
14)服務(wù)器進(jìn)程不同意客戶進(jìn)程激活行方式選項(xiàng)。
15)服務(wù)器進(jìn)程不同意客戶進(jìn)程發(fā)送環(huán)境變量占遥。
16)服務(wù)器進(jìn)程不發(fā)送狀態(tài)信息。
17)這是服務(wù)器進(jìn)程要求客戶進(jìn)程發(fā)送終端類型的子選項(xiàng)输瓜。
18)客戶進(jìn)程把終端類型“IBMPC3”以6字節(jié)的字符串形式發(fā)送給服務(wù)器進(jìn)程瓦胎。
19)服務(wù)器進(jìn)程要求客戶進(jìn)程發(fā)起請(qǐng)求,要求服務(wù)器進(jìn)程激活回顯選項(xiàng)尤揣。這是本例中服務(wù)器進(jìn)程第一次主動(dòng)發(fā)起選項(xiàng)協(xié)商搔啊。
20)客戶進(jìn)程同意由服務(wù)器進(jìn)程實(shí)現(xiàn)回顯功能。
21)服務(wù)器進(jìn)程要求客戶進(jìn)程實(shí)現(xiàn)回顯功能北戏。這個(gè)命令是多余的负芋,它只是將前兩行進(jìn)行了交換。這是目前大多數(shù)Unix的Te lnet服務(wù)器進(jìn)程判斷客戶進(jìn)程是否運(yùn)行4.2BSD或更新的BSD版本時(shí)的一個(gè)方法嗜愈。如果客戶進(jìn)程回送WILL ECHO旧蛾,就表明客戶進(jìn)程運(yùn)行的是老版本的4.2BSD,不支持TCP的緊急方式(在這種情況下就不能采用TCP緊急方式)蠕嫁。
22)客戶進(jìn)程回送WONT ECHO锨天,表示它不是一臺(tái)4.2BSD主機(jī)。
23)對(duì)于客戶進(jìn)程回送的WONT ECHO剃毒,服務(wù)器進(jìn)程以DONT ECHO作為響應(yīng)病袄。
圖26-13顯示的是本例中服務(wù)器進(jìn)程和客戶進(jìn)程交互的時(shí)間系列(去掉了連接建立部分)。
報(bào)文段1包含了圖26-12中的1~8行赘阀。該報(bào)文段中包含24個(gè)字節(jié)數(shù)據(jù)益缠,每個(gè)選項(xiàng)占3個(gè)字節(jié)。這是客戶進(jìn)程發(fā)起的選項(xiàng)協(xié)商基公。該報(bào)文段顯示多個(gè)Telnet選項(xiàng)可以打在一個(gè)TCP段中發(fā)送幅慌。
報(bào)文段3是圖26-12中的第9行,即DO TERMINAL TYPE命令轰豆。報(bào)文段5包含下面的8個(gè)選項(xiàng)協(xié)商中服務(wù)器進(jìn)程的響應(yīng)欠痴,即圖26-12中的1017行迄靠。該報(bào)文段的長(zhǎng)度是27個(gè)字節(jié),因?yàn)?016行是常規(guī)選項(xiàng)喇辽,每個(gè)占3個(gè)字節(jié)掌挚,而17行的子選項(xiàng)部分占6個(gè)字節(jié)。報(bào)文段6包含12個(gè)字節(jié)菩咨,和18行對(duì)應(yīng)吠式,這是客戶發(fā)送它的終端類型的子選項(xiàng)。
報(bào)文段8(53個(gè)字節(jié))包含兩個(gè)Telnet命令和47字節(jié)的輸出數(shù)據(jù)抽米。前面的兩個(gè)服務(wù)器進(jìn)程發(fā)送Telnet命令占6字節(jié)特占,:WILL ECHO和DO ECHO(19和21行)。后47個(gè)字節(jié)的數(shù)據(jù)是:
\r\n\r\nUNIX(r) System V Release 4.0(svr4) \r\n\r\0\r\n\r\0
前面4個(gè)字節(jié)數(shù)據(jù)在字符串輸出之前產(chǎn)生兩個(gè)空行云茸。兩字節(jié)的字符序列“\r\n”在Telnet中被認(rèn)為是換行命令是目,而兩字節(jié)的字符序列“\r\0”則被認(rèn)為是回車命令。這表明數(shù)據(jù)和命令可以在一個(gè)數(shù)據(jù)段中傳輸标捺。Telnet服務(wù)器進(jìn)程和客戶進(jìn)程必須掃描接收到的每個(gè)字符懊纳,尋找IAC字節(jié)并執(zhí)行它后續(xù)的命令。
報(bào)文段9包含客戶進(jìn)程發(fā)送的最后兩個(gè)選項(xiàng):20和22行亡容。23行是報(bào)文段10的響應(yīng)嗤疯,也是服務(wù)器進(jìn)程發(fā)送的最后一個(gè)選項(xiàng)數(shù)據(jù)。
從現(xiàn)在開始闺兢,雙方就可以交互數(shù)據(jù)了茂缚。當(dāng)然在交互數(shù)據(jù)的過程中還可以進(jìn)行選項(xiàng)協(xié)商,我們?cè)谠摾又芯筒欢嘟榻B了屋谭。報(bào)文段12是服務(wù)器進(jìn)程發(fā)送的提示符“l(fā)ogin:”脚囊。報(bào)文段14是用戶輸入的登錄用戶名的第一個(gè)字符,它的回顯在報(bào)文段15中桐磁。這和我們?cè)?9.2節(jié)中介紹的Rlogin交互類似:客戶進(jìn)程每次發(fā)送一個(gè)字符凑术,服務(wù)器進(jìn)程完成回顯工作。
圖26-12中的選項(xiàng)協(xié)商由客戶進(jìn)程初始化的所意,但是在本書中我們已經(jīng)介紹了用Telnet客戶進(jìn)程連接某些標(biāo)準(zhǔn)服務(wù)器進(jìn)程如:日間(daytime)服務(wù)器淮逊、回顯(echo)服務(wù)器等情況。當(dāng)然我們介紹這些的目的是為了描述TCP的各種特性扶踊。但考察這些例子中的分組交換泄鹏,如圖18-1,我們并沒有看到客戶進(jìn)程發(fā)起的選項(xiàng)協(xié)商秧耗。為什么备籽?這是因?yàn)樵赨nix系統(tǒng)中,除非使用標(biāo)準(zhǔn)的Telnet端口號(hào)23,否則客戶進(jìn)程不進(jìn)行選項(xiàng)協(xié)商车猬。這個(gè)特性使得Telnet客戶進(jìn)程可以使用標(biāo)準(zhǔn)的NVT同其他一些非Telnet服務(wù)器進(jìn)程交換數(shù)據(jù)霉猛。我們已經(jīng)在日間服務(wù)器、回顯服務(wù)器和丟棄(discard)服務(wù)器中使用了這個(gè)特性珠闰,在后面章節(jié)介紹FTP和SMTP服務(wù)器的時(shí)候我們還將使用該特性惜浅。
26.5.2 行方式
為了描述Te lnet的行方式選項(xiàng)協(xié)商過程,我們?cè)谥鳈C(jī)bsdi運(yùn)行客戶進(jìn)程伏嗜,服務(wù)器是位于vangogh.vs.berkeley.edu節(jié)點(diǎn)運(yùn)行4.4BSD操作系統(tǒng)的一臺(tái)主機(jī)坛悉。BSD/386和4.4BSD都支持這個(gè)選項(xiàng)。
我們不詳細(xì)討論所有的報(bào)文承绸、選項(xiàng)和子選項(xiàng)協(xié)商過程裸影,因?yàn)檫@個(gè)過程和前面的例子類似,而且對(duì)于行方式選項(xiàng)我們已經(jīng)論述得比較清楚军熏。下面我們僅僅討論在選項(xiàng)協(xié)商中的一些區(qū)別轩猩。
1:對(duì)于BSD/386希望協(xié)商的選項(xiàng)例如:窗口大小、本地流量控制荡澎、狀態(tài)均践、環(huán)境變量和終端速率等,4.4BSD服務(wù)器進(jìn)程都支持衔瓮。
2:4.4BSD服務(wù)器進(jìn)程將協(xié)商一個(gè)BSD/386客戶進(jìn)程不支持的新選項(xiàng):鑒別(為避免以明文形式在網(wǎng)絡(luò)上傳輸用戶口令)。
3:和上個(gè)例子一樣抖甘,客戶進(jìn)程發(fā)送WILL LINEMODE選項(xiàng)热鞍,由于服務(wù)器進(jìn)程支持該選項(xiàng),所以服務(wù)器進(jìn)程發(fā)送DO LINEMODE衔彻。此時(shí)客戶進(jìn)程以子選項(xiàng)形式給服務(wù)器進(jìn)程發(fā)送16個(gè)特定字符薇宠。這些字符是能影響客戶進(jìn)程的特定終端字符值:如中斷字符,文件結(jié)束符等艰额。服務(wù)器進(jìn)程給客戶進(jìn)程發(fā)送一個(gè)子選項(xiàng)澄港,讓客戶進(jìn)程處理所有的輸入,執(zhí)行所有的編輯功能(刪除字符柄沮,刪除行等)回梧。客戶進(jìn)程把除控制字符以外的字符以行的形式發(fā)送給服務(wù)器進(jìn)程祖搓。服務(wù)器進(jìn)程還要求客戶進(jìn)程把所有中斷鍵和信號(hào)鍵轉(zhuǎn)換為相應(yīng)的Te lnet字符狱意。例如中斷鍵是Control_C,我們可以按Control_C來中斷服務(wù)器端的某個(gè)進(jìn)程拯欧∠甓冢客戶進(jìn)程必須把Control_C轉(zhuǎn)換為Telnet的IP命令(<IAC,IP>)傳輸給服務(wù)器進(jìn)程。
4:當(dāng)用戶輸入口令時(shí)情況也有所不同镐作。在Rlogin和一次一字符方式的Te lnet中藏姐,都是由服務(wù)器進(jìn)程負(fù)責(zé)回顯隆箩,所以當(dāng)服務(wù)器進(jìn)程讀到口令時(shí),它并不回顯這些字符羔杨。但在行方式中由客戶進(jìn)程負(fù)責(zé)回顯捌臊。下面這些交互過程將處理這種情況:
a:服務(wù)器進(jìn)程發(fā)送WILL ECHO,以告訴客戶進(jìn)程:服務(wù)器進(jìn)程將處理回顯问畅。
b:客戶進(jìn)程回送DO ECHO娃属。
c:服務(wù)器進(jìn)程向客戶進(jìn)程發(fā)送字符串Password:,客戶進(jìn)程把它發(fā)送到終端上护姆。
d:然后用戶輸入口令矾端,當(dāng)用戶按下RETURN鍵的時(shí)候,客戶進(jìn)程把口令發(fā)送給服務(wù)器進(jìn)程卵皂。此時(shí)口令不回顯秩铆,因?yàn)榭蛻暨M(jìn)程認(rèn)為服務(wù)器進(jìn)程將回顯它。
e:由于口令的結(jié)束符RETURN沒有回顯灯变,服務(wù)器進(jìn)程發(fā)送兩字節(jié)字符序列CR和LF以移動(dòng)光標(biāo)殴玛。
f:服務(wù)器進(jìn)程發(fā)送WONT ECHO。
g:客戶進(jìn)程回送DONT ECHO添祸。然后繼續(xù)由客戶進(jìn)程負(fù)責(zé)回顯滚粟。
一旦登錄完成,客戶進(jìn)程將把數(shù)據(jù)以整行的方式發(fā)送給服務(wù)器進(jìn)程刃泌。這就是行方式選項(xiàng)的目的凡壤。行方式大大地減少了客戶進(jìn)程和服務(wù)器進(jìn)程之間的數(shù)據(jù)交互數(shù)量,而且對(duì)于用戶的擊鍵(也就是回顯和編輯)提供更快的響應(yīng)耙替。圖26-14顯示的是當(dāng)我們輸入命令時(shí)亚侠,在行方式連接下分組交換的情況。
Vangogh %date
(去掉了業(yè)務(wù)種類信息和窗口通告信息)俗扇。
把它和在Rlogin中輸入同樣命令(圖19-2)時(shí)的情況進(jìn)行一下比較硝烂。我們看到在Telnet行方式下只需要2個(gè)報(bào)文段(一個(gè)包含數(shù)據(jù),另一個(gè)用于ACK铜幽,連同IP和TCP首部共86字節(jié))滞谢,而在Rlogin中要發(fā)送15個(gè)報(bào)文段(5個(gè)有鍵入的數(shù)據(jù),5個(gè)有回顯的數(shù)據(jù)除抛,5個(gè)是ACK爹凹,共611字節(jié))∠庖螅可見節(jié)省的數(shù)據(jù)量是非澈探矗可觀的。
如果在服務(wù)器端運(yùn)行一個(gè)需要進(jìn)入單個(gè)字符方式的應(yīng)用程序(例如vi編輯器)會(huì)怎么樣呢?實(shí)際上將發(fā)生如下的一些交互:
1:當(dāng)服務(wù)器的應(yīng)用程序啟動(dòng)了颤陶,并改變其偽終端方式時(shí)颗管,Telnet服務(wù)器進(jìn)程被通告需要進(jìn)入單個(gè)字符方式。然后服務(wù)器發(fā)送WILL ECHO命令和行方式子選項(xiàng)滓走,以告知客戶不要再以行方式工作垦江,轉(zhuǎn)而進(jìn)入單個(gè)字符方式。
2:客戶響應(yīng)以DO ECHO搅方,并確認(rèn)行方式子選項(xiàng)比吭。
3:應(yīng)用程序在服務(wù)器上運(yùn)行。我們鍵入的每個(gè)字符將發(fā)送到服務(wù)器(當(dāng)然要強(qiáng)制使用Nagle算法)姨涡,此時(shí)服務(wù)器將處理必要的回顯工作衩藤。
4:當(dāng)應(yīng)用程序終止時(shí),就恢復(fù)其偽終端方式涛漂,并通告Telnet服務(wù)器赏表。服務(wù)器將向客戶發(fā)送WONT ECHO命令,同時(shí)發(fā)送行方式子選項(xiàng)匈仗,告訴客戶恢復(fù)進(jìn)入行方式瓢剿。
5:客戶響應(yīng)DONT ECHO,確認(rèn)進(jìn)入行方式悠轩。
上述情況同我們鍵入口令之間的區(qū)別表明:回顯功能和單個(gè)字符方式與一次一行方式?jīng)]有依賴關(guān)系间狂。當(dāng)我們鍵入口令時(shí),回顯功能必須失效火架,但一次一行方式有效鉴象。對(duì)于一個(gè)全屏應(yīng)用來講,例如編輯器距潘,回顯必須失效而單個(gè)字符方式必須有效炼列。
圖26-15概括了Rlogin和Telnet不同方式之間的差異只搁。
26.5.3 一次一行方式(準(zhǔn)行方式)
從圖26-11可以看出音比,如果客戶不支持行方式,那么較新的服務(wù)器支持行方式選項(xiàng)氢惋,它也將轉(zhuǎn)入準(zhǔn)行方式(Kludge line mode)洞翩。我們同時(shí)指出所有的客戶進(jìn)程和服務(wù)器進(jìn)程都支持準(zhǔn)行方式,但它不是默認(rèn)方式焰望,必須由客戶進(jìn)程或用戶特地激活它骚亿。讓我們來看看如何用Telnet選項(xiàng)激活準(zhǔn)行方式。
首先介紹當(dāng)客戶進(jìn)程不支持行方式時(shí)熊赖,BSD/386服務(wù)器進(jìn)程如何協(xié)商進(jìn)入該方式来屠。
1:當(dāng)客戶進(jìn)程不同意服務(wù)器進(jìn)程激活行方式的請(qǐng)求時(shí),服務(wù)器進(jìn)程發(fā)送DO TIMING MARK選項(xiàng)。RFC 860 [Postel和Reynolds 1983f]定義了這個(gè)Telnet選項(xiàng)俱笛。它的作用是讓收發(fā)雙方同步捆姜,關(guān)于這個(gè)問題將在本節(jié)的后面講到用戶鍵入中斷鍵時(shí)討論。該選項(xiàng)只是用來判斷客戶進(jìn)程是否支持準(zhǔn)行方式迎膜。
2:客戶響應(yīng)WILL TIMING MARK泥技,表明支持準(zhǔn)行方式。
3:服務(wù)器發(fā)送WONT SUPPRESS GO AHEAD和WONT ECHO選項(xiàng)磕仅,告訴客戶它希望禁止這兩個(gè)選項(xiàng)珊豹。我們?cè)谇懊嬉呀?jīng)強(qiáng)調(diào):?jiǎn)蝹€(gè)字符方式下是假定SUPPRESS GO AHEAD和ECHO選項(xiàng)同時(shí)有效的,所以禁止兩個(gè)選項(xiàng)就進(jìn)入了準(zhǔn)行方式榕订。
4:客戶響應(yīng)DONT SUPPRESS GO AHEAD和DONT ECHO命令店茶。
5:服務(wù)器發(fā)送login:提示符,然后用戶鍵入用戶名卸亮。用戶名是以整行的方式發(fā)送給服務(wù)器忽妒,回顯由客戶進(jìn)程在本地處理。
6:服務(wù)器發(fā)送Password:提示符和WILL ECHO命令兼贸。這將使客戶進(jìn)程的回顯失效段直,因?yàn)榇藭r(shí)客戶進(jìn)程認(rèn)為服務(wù)器進(jìn)程將處理回顯工作,所以用戶鍵入的口令就不回顯到屏幕上溶诞⊙烀剩客戶響應(yīng)DO ECHO命令。
7:我們鍵入口令螺垢⌒瘢客戶以整行方式發(fā)送到服務(wù)器。
8:服務(wù)器發(fā)送WONT ECHO命令枉圃,使得客戶重新激活回顯功能功茴,客戶響應(yīng)DONT ECHO。從此以后的普通命令處理過程就和行方式相似了孽亲】泊客戶進(jìn)程負(fù)責(zé)所有的編輯和回顯,并以整行的方式發(fā)送給服務(wù)器進(jìn)程返劲。
在圖26-11中玲昧,我們已經(jīng)強(qiáng)調(diào):所有標(biāo)注為“char”的記錄都支持準(zhǔn)行方式,只不過默認(rèn)是單個(gè)字符方式罷了篮绿。如果要客戶進(jìn)入行方式孵延,我們就能很容易看到選項(xiàng)協(xié)商的過程:
這將使Telnet會(huì)話進(jìn)入準(zhǔn)行方式,此時(shí)SUPPRESS GO AHEAD和ECHO選項(xiàng)都是失效的亲配。
如果在服務(wù)器端運(yùn)行如vi編輯器這樣的應(yīng)用程序尘应,同樣會(huì)有行方式下遇到的問題惶凝。當(dāng)要運(yùn)行這樣的應(yīng)用程序時(shí),服務(wù)器進(jìn)程必須告訴客戶進(jìn)程從準(zhǔn)行方式切換到單字符方式犬钢。當(dāng)應(yīng)用程序結(jié)束時(shí)梨睁,必須告訴客戶進(jìn)程返回到準(zhǔn)行方式。下面是這個(gè)過程需要用到的技術(shù)要點(diǎn)娜饵。
1:當(dāng)應(yīng)用程序改變其偽終端方式并通知服務(wù)器進(jìn)程時(shí)坡贺,服務(wù)器進(jìn)程將進(jìn)入單字符方式。服務(wù)器進(jìn)程向客戶進(jìn)程發(fā)送WILL SUPPRESS GO AHEAD和WILL ECHO箱舞,這將使客戶進(jìn)程進(jìn)入單字符方式遍坟。
2:客戶進(jìn)程回送DO SUPPRESS GO AHEAD和WILL ECHO。
3:應(yīng)用程序開始在服務(wù)器端運(yùn)行晴股。
4:當(dāng)應(yīng)用程序結(jié)束并改變其偽終端方式時(shí)愿伴,服務(wù)器進(jìn)程發(fā)送WONT SUPPRESS GO AHEAD和WONT ECHO命令,使得客戶進(jìn)程返回準(zhǔn)行方式电湘。
5:客戶進(jìn)程回送DONT SUPPRESS GO AHEAD和DONT ECHO命令隔节,告訴服務(wù)器進(jìn)程它已經(jīng)回到了準(zhǔn)行方式。
圖26-16概括了單個(gè)字符方式及準(zhǔn)行方式中不同的SUPPRESS GO AHEAD和ECHO選項(xiàng)設(shè)置寂呛。
26.5.4 行方式:客戶中斷鍵
看一下當(dāng)用戶鍵入中斷鍵時(shí)Telnet將發(fā)生什么情況怎诫。假定在客戶主機(jī)bsdi和服務(wù)器cangogh.cs.berkeley.edu之間建立了一個(gè)Telnet會(huì)話。圖26-17顯示了當(dāng)用戶鍵入中斷鍵后的時(shí)間系列(去掉了窗口通告和服務(wù)類型)贷痪。
報(bào)文段1中顯示的是中斷鍵(通常是Control_C或DELETE)已經(jīng)轉(zhuǎn)換為Telnet的IP(中斷進(jìn)程)命令:<IAC,IP>幻妓。下面的3個(gè)字節(jié):<IAC,DO,TM>,組成了Telnet的DO TIMING MARK選項(xiàng)劫拢。這個(gè)標(biāo)志由客戶進(jìn)程發(fā)送肉津,必須使用WILL或WONT響應(yīng)。所有在響應(yīng)前收到的數(shù)據(jù)都要丟棄(除非是Telnet命令)舱沧。這是服務(wù)器進(jìn)程和客戶機(jī)端的同步過程妹沙。報(bào)文段1沒有采用TCP緊急方式。
Host Requirements RFC敘述了IP命令不能使用Te lnet的同步信號(hào)來發(fā)送熟吏。如果可以的話距糖,那么<IAC,IP>的后面將跟隨<IAC,DM>,同時(shí)緊急指針指向DM字節(jié)分俯。大多數(shù)的Unix Telnet客戶有一個(gè)選項(xiàng)來使用同步信號(hào)發(fā)送IP命令肾筐,但是這個(gè)選項(xiàng)默認(rèn)是不用的(正如我們這里看到的)哆料。
報(bào)文段2是服務(wù)器進(jìn)程對(duì)DO TIMING MARK選項(xiàng)的響應(yīng)缸剪。緊隨其后的是報(bào)文段3和4中Telnet的同步信號(hào):<IAC,DM>。報(bào)文段3中的緊急指針指向?qū)⒃趫?bào)文段4中發(fā)送的DM字節(jié)东亦。
如果服務(wù)器進(jìn)程到客戶進(jìn)程的窗口已滿杏节,那么客戶進(jìn)程發(fā)送了如報(bào)文段1中的IP命令后就丟棄收到的所有數(shù)據(jù)唬渗。即使服務(wù)器進(jìn)程被TCP流量控制所終止而不能發(fā)送如報(bào)文段2、3和4中的數(shù)據(jù)奋渔,緊急指針仍然可以發(fā)送镊逝。這和圖26-7中的Rlogin類似。
為什么同步信號(hào)要分為兩個(gè)數(shù)據(jù)段發(fā)送(3和4)嫉鲸?原因就是我們?cè)?0.8節(jié)中詳細(xì)討論TCP緊急指針時(shí)提到的情況撑蒜。有關(guān)主機(jī)需求的RFC中提到緊急指針應(yīng)指向緊急數(shù)據(jù)的最后一個(gè)字節(jié),而很多衍生于伯克利的系統(tǒng)中玄渗,緊急指針指向緊急數(shù)據(jù)的倒數(shù)第2個(gè)字節(jié)(回憶一下在圖26-6中座菠,緊急指針指向命令字節(jié)的前一個(gè)字節(jié))。Telnet服務(wù)器進(jìn)程故意把同步信號(hào)的第1個(gè)字節(jié)作為緊急數(shù)據(jù)藤树,它知道緊急指針將指向下1個(gè)字節(jié)(即DM字節(jié))浴滴,而IAC字節(jié)和緊急指針必須立即發(fā)送,在下一步才發(fā)送DM字節(jié)岁钓。
最后一個(gè)報(bào)文段6發(fā)送的是數(shù)據(jù)升略,它是服務(wù)器進(jìn)程發(fā)生的提示符。
26.6 小結(jié)
本章我們介紹了Rlogin和Telnet操作屡限。兩者都提供了從客戶進(jìn)程遠(yuǎn)程登錄到服務(wù)器進(jìn)程品嚣,是我們能夠在服務(wù)器端運(yùn)行程序的方法。
這兩個(gè)應(yīng)用是不同的钧大。Rlogin假定連接的雙方都是Unix系統(tǒng)腰根,所以只提供一個(gè)選項(xiàng),它是1個(gè)簡(jiǎn)單的協(xié)議拓型。Telnet則不同额嘿,它用于在不同類型的主機(jī)之間建立連接。
為了支持這種多機(jī)環(huán)境劣挫,Telnet提供客戶進(jìn)程和服務(wù)器進(jìn)程的選項(xiàng)協(xié)商機(jī)制册养。如果連接的雙方都支持這些選項(xiàng),則可以增強(qiáng)一些功能压固。對(duì)于比較簡(jiǎn)單的客戶進(jìn)程和服務(wù)器進(jìn)程球拦,它可以提供Telnet的基本功能,而當(dāng)雙方都支持某些選項(xiàng)時(shí)帐我,它又可以充分利用雙方的新特性坎炼。
我們介紹了Telnet的選項(xiàng)協(xié)商機(jī)制,也介紹了3種數(shù)據(jù)傳輸?shù)姆绞剑簡(jiǎn)巫址绞嚼辜?zhǔn)行方式和實(shí)行方式∫ス猓現(xiàn)在的趨勢(shì)是只要有可能,就盡量工作在準(zhǔn)行方式下芬为。這樣可以減少網(wǎng)絡(luò)上的數(shù)據(jù)量萄金,同時(shí)為交互用戶提供更好的行編輯和回顯的響應(yīng)蟀悦。
圖26-18概括并比較了Rlogin和Telnet的不同特性。
Rlogin服務(wù)器和Telnet服務(wù)器通常都將設(shè)置TCP的毖醺遥活選項(xiàng)以檢測(cè)客戶主機(jī)是否崩潰(如果服務(wù)器的TCP實(shí)現(xiàn)支持日戈,見第23章)。這兩種應(yīng)用都采用了TCP緊急方式孙乖,以便即使從服務(wù)器到客戶的數(shù)據(jù)傳輸被流量控制所終止浙炼,服務(wù)器仍然可以向客戶發(fā)送命令。