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

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


