天天看點

《Linux高性能伺服器程式設計》——3.6 TCP互動資料流

前面讨論了tcp連接配接及其狀态,從本節開始我們讨論通過tcp連接配接交換的應用程式資料。tcp封包段所攜帶的應用程式資料按照長度分為兩種:互動資料和成塊資料。互動資料僅包含很少的位元組。使用互動資料的應用程式(或協定)對實時性要求高,比如telnet、ssh等。成塊資料的長度則通常為tcp封包段允許的最大資料長度。使用成塊資料的應用程式(或協定)對傳輸效率要求高,比如ftp。本節我們讨論互動資料流。

考慮如下情況:在ernest-laptop上執行telnet指令登入到本機,然後在shell指令提示符後執行ls指令,同時用tcpdump抓取這一過程中telnet用戶端和telnet伺服器交換的tcp封包段。具體操作過程如下:

上述過程将引起用戶端和伺服器交換很多tcp封包段。下面我們僅列出我們感興趣的、執行ls指令産生的tcpdump輸出,如代碼清單3-4所示。

《Linux高性能伺服器程式設計》——3.6 TCP互動資料流

tcp封包段1由用戶端發送給伺服器,它攜帶1個位元組的應用程式資料,即字母“l”。tcp封包段2是伺服器對tcp封包段1的确認,同時回顯字母“l”。tcp封包段3是用戶端對tcp封包段2的确認。第4~6個tcp封包段是針對字母“s”的上述過程。tcp封包段7傳送的2位元組資料分别是:用戶端鍵入的回車符和流結束符(eof,本例中是0x00)。tcp封包段8攜帶伺服器傳回的客戶查詢的目錄的内容(ls指令的輸出),包括該目錄下檔案的檔案名及其顯示控制參數。tcp封包段9是用戶端對tcp封包段8的确認。tcp封包段10攜帶的也是伺服器傳回給用戶端的資料,包括一個回車符、一個換行符、用戶端登入使用者的ps1環境變量(第一級指令提示符)。tcp封包段11是用戶端對tcp封包段10的确認。

在上述過程中,用戶端針對伺服器傳回的資料所發送的确認封包段(tcp封包段6、9和11)都不攜帶任何應用程式資料(長度為0),而伺服器每次發送的确認封包段(tcp封包段2、5、8和10)都包含它需要發送的應用程式資料。伺服器的這種處理方式稱為延遲确認,即它不馬上确認上次收到的資料,而是在一段延遲時間後檢視本端是否有資料需要發送,如果有,則和确認資訊一起發出。因為伺服器對客戶請求處理得很快,是以它發送确認封包段的時候總是有資料一起發送。延遲确認可以減少發送tcp封包段的數量。而由于使用者的輸入速度明顯慢于用戶端程式的處理速度,是以用戶端的确認封包段總是不攜帶任何應用程式資料。前文曾提到,在tcp連接配接的建立和斷開過程中,也可能發生延遲确認。

上例是在本地回路運作的結果,在區域網路中也能得到基本相同的結果,但在廣域網就未必如此了。廣域網上的互動資料流可能經受很大的延遲,并且,攜帶互動資料的微小tcp封包段數量一般很多(一個按鍵輸入就導緻一個tcp封包段),這些因素都可能導緻擁塞發生。解決該問題的一個簡單有效的方法是使用nagle算法。

nagle算法要求一個tcp連接配接的通信雙方在任意時刻都最多隻能發送一個未被确認的tcp封包段,在該tcp封包段的确認到達之前不能發送其他tcp封包段。另一方面,發送方在等待确認的同時收集本端需要發送的微量資料,并在确認到來時以一個tcp封包段将它們全部發出。這樣就極大地減少了網絡上的微小tcp封包段的數量。該算法的另一個優點在于其自适應性:确認到達得越快,資料也就發送得越快。

繼續閱讀