Rlogin的第一次發(fā)布是在4.2BSD中,當時它僅能實現(xiàn)Unix主機之間的遠程登錄。這就使得Rlogin比Telnet簡單。由于客戶進程和服務(wù)器進程的操作系統(tǒng)預(yù)先都知道對方的操作系統(tǒng)類型,所以就不需要選項協(xié)商機制。在過去的幾年中,Rlogin協(xié)議也派生出幾種非Unix環(huán)境的版本。
RFC1282[Kantor1991]具體說明了Rlogin協(xié)議。類似于選路信息協(xié)議(Rip)的RFC,它是Rlogin用了許多年后才發(fā)布的。[Stevens1990]的第15章介紹了遠程登錄的客戶進程及服務(wù)器進程端的編程,并且給出了Rlogin的客戶進程及服務(wù)器進程的完整源代碼。[Comer和Stevens1993]的第25章和第26章給出了Telnet的客戶進程的實現(xiàn)細節(jié)和源代碼。
應(yīng)用進程的啟動
Rlogin的客戶進程和服務(wù)器進程使用一個TCP連接。當普通的TCP連接建立完畢之后,客戶進程和服務(wù)器進程之間將發(fā)生下面所述的動作。
1)客戶進程給服務(wù)器進程發(fā)送4個字符串:(a)一個字節(jié)的0;(b)用戶登錄進客戶進程主機的登錄名,以一個字節(jié)的0結(jié)束;(c)登錄服務(wù)器進程端主機的登錄名,以一個字節(jié)的0結(jié)束;(d)用戶終端類型名,緊跟一個正斜杠“/”,然后是終端速率,以一個字節(jié)的0結(jié)束。在這里需要兩個登錄名字,這是因為用戶登錄客戶和服務(wù)器的名稱有可能不一樣。由于大多滿屏應(yīng)用程序需要知道終端類型,所以終端類型也必須發(fā)送到服務(wù)器進程。發(fā)送終端速率的原因是因為有些應(yīng)用隨著速率的改變,它的操作也有所變化。例如vi編輯器,當速率比較小的時候,它的工作窗口也變小。所以它不能永遠保持同樣大小的窗口。
2)服務(wù)器進程返回一個字節(jié)的0。
3)服務(wù)器進程可以選擇是否要求用戶輸入口令。這個步驟的數(shù)據(jù)交互沒有什么非凡的協(xié)議,而被當作是普通的數(shù)據(jù)進行傳輸。服務(wù)器進程給客戶進程發(fā)送一個字符串(顯示在客戶進程的屏幕上),通常是passWord:。假如在一定的限定時間內(nèi)(通常是60秒)客戶進程沒有輸入口令,服務(wù)器進程將關(guān)閉該連接。通常可以在服務(wù)器進程的主目錄(homeDirectory)下生成一個文件(通常叫.rhosts),該文件的某些行記錄了一個主機名和用戶名。假如從該文件中已經(jīng)記錄的主機上用已經(jīng)記錄的用戶名進行登錄,服務(wù)器進程將不提示我們輸入口令。但是很多關(guān)于安全性的文獻,如[Curry1992],強烈建議不要采用這種方法,因為這存在安全漏洞。假如提示輸入口令,那么我們輸入的口令將以明文的形式發(fā)送到服務(wù)器進程。我們所鍵入的每個字符都是以明文的格式傳輸?shù)摹K阅橙酥灰軌蚪厝【W(wǎng)絡(luò)上的原始傳輸?shù)姆纸M,他就可以截獲用戶口令。針對這個問題,新版本的Rlogin客戶程序,例如
4.4BSD版本的客戶程序,第一次采用了Kerberos安全模型。Kerberos安全模型可以避免用戶口令以明文的形式在網(wǎng)絡(luò)上傳輸。當然,這要求服務(wù)器進程也支持Kerberos
([Curry1992]具體描述了Kerberos安全模型)。4)服務(wù)器進程通常要給客戶進程發(fā)送請求,詢問終端的窗口大小(將在后面解釋)。客戶進程每次給服務(wù)器進程發(fā)送一個字節(jié)的內(nèi)容,并且接收服務(wù)器進程的所有返回信息。
同樣我們也采用了Nagle算法(在19.4節(jié)中曾經(jīng)介紹),該算法可以保證在速率較低的網(wǎng)絡(luò)上,若干輸入字節(jié)以單個TCP報文段傳輸。操作其實很簡單:用戶鍵入的所有東西被發(fā)送到服務(wù)器,服務(wù)器發(fā)送給客戶的任何信息返回到用戶的屏幕上。
另外,服務(wù)器和客戶之間還可以互相發(fā)送命令。在介紹這些命令之前,先介紹需要用到這些命令。
流量控制
默認情況下,流量控制是由Rlogin的客戶進程完成的。客戶進程能夠識別用戶鍵入的STOP和START的ASCII字符(ControlS和ControlQ),并且終止或啟動終端的輸出。
假如不是這樣,每次我們?yōu)榻K止終端輸出而鍵入的Control_S字符將沿網(wǎng)絡(luò)傳輸?shù)椒?wù)器進程,這時服務(wù)器進程將停止往網(wǎng)絡(luò)上寫數(shù)據(jù)。但是在寫操作終止之前,服務(wù)器進程可能已經(jīng)往網(wǎng)絡(luò)上寫了一窗口的輸出數(shù)據(jù)。也就是說,在輸出停止之前,成千上萬的數(shù)據(jù)字節(jié)還將在屏幕上顯示。圖26-3顯示了這個情況。

客戶的中斷鍵
當我們?yōu)橹袛喾?wù)器正在運行的進程而鍵入一個中斷字符時(通常是DELETE或Control_C),會發(fā)生和流量控制相同的問題。這個情況和圖26-3所示的類似,在一條TCP連接的管道上,從服務(wù)器進程向客戶進程正在發(fā)送大量的數(shù)據(jù),而客戶進程同時在向服務(wù)器進程傳輸中斷字符。而我們的本意是要中斷字符盡快終止某個進程,使屏幕上不再有任何響應(yīng)輸出。
在流量控制和中斷鍵這兩種情況中,流量控制機制很少終止客戶進程到服務(wù)器進程的數(shù)據(jù)流。這個方向僅僅包含我們鍵入的字符。所以對于從客戶輸出到服務(wù)器的非凡輸入字符(Control_S和中斷字符)不需要采用TCP的緊急方式(urgentmode)。
窗口大小的改變
假如是窗口風(fēng)格的顯示方式,當應(yīng)用程序在運行的時候,我們還可以動態(tài)地改變窗口的大小。一些應(yīng)用程序(典型的如那些操作整個窗口的應(yīng)用程序,如全屏編輯器)需要知道窗口大小的變化。目前大多數(shù)Unix系統(tǒng)提供這種功能,可以告訴應(yīng)用程序關(guān)于窗口大小的變化。
對于遠程登錄這種情況,窗口大小的變化發(fā)生在客戶端,而運行在服務(wù)器端的應(yīng)用程序需要知道窗口大小變化。所以Rlogin的客戶需要采用某些方法來通知服務(wù)器窗口大小變化的情況以及新窗口的大小。
服務(wù)器到客戶的命令
現(xiàn)在我們介紹通過TCP連接,Rlogin服務(wù)器進程可以發(fā)送給客戶進程的4條命令。問題是只有一條TCP連接可供使用,所以服務(wù)器進程必須給這些命令字節(jié)做標記,使得客戶進程可以從數(shù)據(jù)流中識別出這些是命令,而不是顯示在終端上。所以我們將使用TCP的緊急方式(在20.8節(jié)中曾經(jīng)介紹)。
當服務(wù)器要給客戶發(fā)送命令時,服務(wù)器就進入緊急方式,并且把命令放在緊急數(shù)據(jù)的最后一個字節(jié)中。當客戶進程收到這個緊急方式通知時,它從連接上讀取數(shù)據(jù)并且保存起來,直到讀到命令字節(jié)(即緊急數(shù)據(jù)的最后一個字節(jié))。這時候客戶進程根據(jù)讀到的命令,再決定對于所讀到并保存起來的數(shù)據(jù)是顯示在終端上還是丟棄它。
采用TCP緊急方式發(fā)送這些命令的一個原因是第一個命令(“清倉輸出(flushoutput)”)需要立即發(fā)送給客戶,即使服務(wù)器到客戶的數(shù)據(jù)流被窗口流量控制所終止。這種情況下,即服務(wù)器到客戶的輸出被流量控制所終止的情況是經(jīng)常發(fā)生的,這是因為運行在服務(wù)器的進程的輸出速率通常大于客戶終端的顯示速率。另一方面,客戶到服務(wù)器的數(shù)據(jù)流很少被流量控制所終止,因為這個方向的數(shù)據(jù)流僅僅包含用戶所鍵入的字符。
客戶到服務(wù)器的命令
對于客戶到服務(wù)器的命令,只定義了一條命令,那就是:將當前窗口大小發(fā)送給服務(wù)器。當客戶的窗口大小發(fā)生變化時,客戶并不立即向服務(wù)器報告,除非收到了服務(wù)器發(fā)來的0x80命令(圖26-4中有介紹)。
同樣,由于只存在一條TCP連接,客戶必須對在連接上傳輸?shù)脑撁钭止?jié)進行標注,使得服務(wù)器可以從數(shù)據(jù)流中識別出命令,而不是把它發(fā)送到上層的應(yīng)用程序中去。處理的方法就是在兩個字節(jié)的0xff后面緊跟著發(fā)送兩個非凡的標志字節(jié)。
對于窗口大小命令,兩個標志字節(jié)是ASCII碼的字符‘s’。之后是4個16bit長的數(shù)據(jù)(按網(wǎng)絡(luò)字節(jié)順序),分別是:行數(shù)(例如,25),每列的字符數(shù)(例如,80),X方向的像素數(shù)量,Y方向的像素數(shù)量。通常情況下,后兩個16bit是0,因為在Rlogin服務(wù)器進程調(diào)用的應(yīng)用程序中,通常是以字符為單位來度量屏幕的,而不是像素點。
上面我們介紹的從客戶進程到服務(wù)器進程的命令采用帶內(nèi)信令(in-bandsignaling),這是因為命令字節(jié)和其他的普通數(shù)據(jù)一起傳輸。選擇0xff字節(jié)來表示這個帶內(nèi)信令的原因是:一般用戶的操作不會產(chǎn)生0xff這個字節(jié)。所以說Rlogin是不完備的,假如我們采用某種方法,使得通過鍵盤就可以產(chǎn)生兩個連續(xù)的0xff字節(jié),而且正好在這之前是兩個ASCII的‘s’字符,那么下面的8個字節(jié)就會被誤認為是窗口大小了。
圖26-4中介紹的是從服務(wù)器到客戶的Rlogin命令,由于大多數(shù)的API采用的技術(shù)叫做“帶外數(shù)據(jù)(out-of-banddata)”,所以我們就稱它為帶外信令(out-of-bandsignaling)。但是回憶一下在20.8節(jié)中對TCP緊急方式的討論,在那里我們說緊急方式數(shù)據(jù)不是帶外數(shù)據(jù),命令字節(jié)是按照普通數(shù)據(jù)流進行傳輸?shù)模欠仓幨遣捎昧司o急指針。
既然帶內(nèi)信令被用來傳輸從客戶到服務(wù)器的命令,那么服務(wù)器進程必須檢查從客戶進程收到的每個字節(jié),看看是否有兩個連續(xù)的0xff字節(jié)。但是對于采用帶外信令的、從服務(wù)器傳輸?shù)降娇蛻舻拿睿蛻暨M程不需要檢查收到的每個字節(jié),除非服務(wù)器進程進入了緊急方式。即使在緊急方式下,客戶進程也僅僅需要留意緊急指針所指向的字節(jié)。而且由于從客戶進程到服務(wù)器的數(shù)據(jù)流量和相反方向的數(shù)據(jù)流量之比是1:20,這就暗示帶內(nèi)信令適合于數(shù)據(jù)量比較小的情況(從客戶到服務(wù)器),而帶外信令適合于數(shù)據(jù)量比較大的情況(從服務(wù)器到客戶)。
客戶的轉(zhuǎn)義符
通常情況下,我們向Rlogin客戶進程鍵入的信息將傳輸?shù)椒?wù)器進程。但是有些時候,我們并不需要把鍵入的信息傳輸?shù)椒?wù)器,而是要和Rlogin客戶進程直接通信。方法是在一行的開頭鍵入代字符(tilde)“~”,緊跟著是下列4個字符之一:
1)以一個句號結(jié)束客戶進程。
2)以文件結(jié)束符(通常是Control_D)結(jié)束客戶進程。
3)以任務(wù)控制掛起符(通常是Control_Z)掛起客戶進程。
4)以任務(wù)控制延遲掛起符(通常是Control_Y)來掛起僅僅是客戶進程的輸入。這時,不管客戶運行什么程序,鍵入的任何信息將由該程序進行解釋,但是從服務(wù)器發(fā)送到客戶的信息還是輸出到終端上。這非常適合當我們需要在服務(wù)器上運行一個長時間程序的場合,我們既想知道該程序的輸出結(jié)果,同時還想在客戶上運行其他程序。只有當客戶進程的Unix系統(tǒng)支持任務(wù)控制時,后兩個命令才有效。
新聞熱點
疑難解答
圖片精選