TCP/IP 協定與 Internet 網路:第七章 傳輸層協定 上一頁 下一頁
7-4 TCP 流量控制
TCP 主要的功能是希望在不可靠的網路裡,建構一個可靠的傳輸環境。依照我們的了解 Internet 網路為了能連結不同網路型態,又希望跨接各偏遠地區的網路,而採用在網路層上以變異性較高的 IP 協定。IP 協定最主要的特點是連結性較高,但相對應的可靠性也較低,當傳送端發送封包後,也許此封包會在傳送中遺失,或是被傳送端重複傳送,或連續的封包到達目的地後,次序已發生錯亂,甚至封包在傳送中已被外來訊號干擾,而發生資料錯誤,等等這些問題,基本上 IP 協定並沒有能力去檢定這些可能發生的錯誤,這都必須由 TCP 協定來偵測出,並從事補救的措施,由此可以看出 TCP 流量控制就顯得非常重要。
何謂『流量控制』(Flow Control)?是在已建立完成的連線上從事資料傳輸的控制方法,並且以何種方法可將傳輸連線的使用率提昇到最高?流量控制除了管理資料在通訊連線上傳輸的順序外,還牽涉到傳送端和接收端緩衝器多寡的管理問題。當電腦欲傳送資料時,將資料以每次傳送封包大小,依序填入『傳送緩衝器』(Send Buffer)內。當傳送端將資料封包傳送出去後,可能必須經過一段時間後才能到達接收端,接收端是否正常收到資料?如何回應給傳送端?如果發生問題怎樣重送?傳送端必須確認該訊號已正常傳送完畢,才可將資料封包由傳送緩衝器上刪除,因此在大量連續傳送資料中傳送緩衝器就必須很大。在接收端也必須有一個叫『接收緩衝器』(Received Buffer),接收到資料後判斷資料正常便填入緩衝器內,但因為通訊連線也許很長,每一筆資料封包到達的時間不一定相同,到達的資料封包不一定按照原來封包順序,也可能在一串的封包內其中有幾個封包發生錯誤。因此有幾個封包是重新傳送?有幾個封包是重複傳送?接收緩衝器必須將接收到的封包按序號排列,才可傳送給上層通訊軟體,所以接收緩衝器有可能要很大。當然由技術層面來講,我們希望流量控制的技術儘可能減少緩衝器的需求。可是不論傳送緩衝器或接收緩衝器都不可能無限的擴充,如何重複使用緩衝器以減低緩衝器需求也是流量控制的重要項目之一。
7-4-1 停止與等待法
我們以圖 7-14 來說明最簡單的流量控制法,此方法又稱為『停止與等待』(Stop-and-Wait)。其表示傳送端(TP_A)將資料送出後必須等待接收端(TP_B)回應,再決定是否繼續傳送下一筆資料。如果回應接收正常(Ack)便傳送下一筆資料;如果溢時(Time out)未收到回應或收到回應不確認訊息(Nak),則需重新傳送該筆資料。
圖 7-14 停止與等待流量控制
由圖 7-14 中我們可以發現停止與等待法,通訊中兩端花費太多的等待時間(大部分時間都在等待對方回應),但其優勢在於處理方法簡單,所以對近距離(回應時間較短)或要求快速反應的設備大部分採用此方法。而且由於傳送和接收雙方只要一個緩衝器便可,一般適用於主機電腦內,或電腦機房內各處理設備之間資料的傳輸,對於遠距離 Internet 網路的傳輸便不適合。以下我們接介紹較適合於網路上使用的滑動視窗法。
7-4-2 滑動視窗法
『滑動視窗法』(Sliding Window)的功能是當建立連線後,我們希望能充分利用這條連線來傳輸資料(連接導向服務),如果採用停止與等待方法,通訊連線大部分時間都是空閒著,傳輸效率太差。滑動視窗法可連續傳送多筆資料,接收端只要回應目前已正確接收到第幾筆資料,一次確認多筆資料,網路上可連續傳送多筆資料,提高網路的使用率。
(A) 運作原理
TCP 連線是屬於全雙工傳輸方式,也就是說,雙方建立 TCP 連線後,這條連線允許雙方同時傳送資料。我們利用圖 7-15 來說明滑動視窗法如何來控制雙向傳輸的基本原理。首先假設上層通訊軟體有一筆資料(1Mbytes)希望借由 TCP_A 傳送給 TCP_B 的上層通訊軟體,此時 TCP_A 會依照『傳送緩衝器』(Send Buffer)的空間大小(假設 300 Kbyte)填入該筆資料,再依序由緩衝器上取出每一傳送封包長度(一般皆為1460 Bytes)的資料,組裝後傳送給下層通訊軟體(IP 層),並在每一封包上給予兩個序號:(如圖 7-3 中 TCP 封包的 Sequence Number 與 Acknowledge Number欄位)
● seq(Sequence Number):表示目前傳送封包的序號。
● ack(acknowledge Number):表示期望對方下次傳送給我之封包序號,也就是說下次對方傳給我的封包的 seq。也表示該序號以前的資料都已正常接收。
TCP 封包順序號碼的編碼如下:當 TCP 準備傳送資料時,便由亂數中取一個 32 位元數字當作起始的順序號碼(Sequence Number)(或 seq),而確認序號(Acknowledge Number)(或 ack)不用填入任何值。接收端收到該封包後,計算封包內資料的位元組長度(Length)(或 len),再以收到的順序號碼(seq)加上資料長度(len)後(以 Bytes 為單位),填入確認序號欄位(ack = seq + len),並回應給傳送端。傳送端由對方回應的確認號碼得知是否成功傳送封包。
我們用圖 7-15 來說明滑動視窗的運作程序,假設每個封包長度為 10 個位元組(Bytes),TP_A 連續傳送 3 個封包給 TP_B,而順序號碼為 seq =20、30、40。又每一封包上皆是 ack = 20,也表示之前 TCP_B 送給 TCP_A 的順序號碼 20 以前的資料都已正常接收,期望下一次 TCP_B 送來的順序序號為 20。
圖 7-15 滑動視窗法基本原理之一
如果 TCP_B 接收到上列資料(圖 7-15)後處理如下:(1) 由 ack = 20,得知先前所送順序號碼 20 以前的資料對方都正常接收,並清除該資料所佔用的緩衝器空間;(2) 又再利用檢查集(Checksum)錯誤檢出法檢查封包資料(seq = 20、30、40)有沒有損壞,如正常便依序填入接收緩衝器(Receive Buffer)內,再依照最後序號 40 加上該筆資料長度(40 + 10),而以 ack = 50,表示前面的資料都已接收正常;(3) 有可能此時 TCP_B 也有資料要傳送給 TCP_A,因此,就將 ack(50) 訊號附加在傳送封包上。如圖 7-16,TCP_B 連續傳送兩個封包給 TCP_A,其中封包訊號為(seq = 20、ack = 50)與(seq = 30、ack = 50)。TCP_A 接收到 ack = 50,便知道序號 50 以前的資料都傳送正常,便清除它們的緩衝器,並將這兩個封包存入接收緩衝器上。此時 TP_A 的傳送緩衝器就空閒起來,便可再填入欲傳送的資料(50 ~ 99),並等待下次傳送。
圖 7-16 滑動視窗法基本原理之二
(B) 傳送視窗與接收視窗
由圖 7-15 和 7-16 可以觀察到,傳送緩衝器如果以串列排列,前端緩衝器不停的傳送到連線上,而緩衝器的後端必需不停的上層通訊軟體填入封包,如此該串列緩衝器將無限的往前延伸,而緩衝器也無法重複使用。我們可以用另一種環狀序列來排列緩衝器,如圖 7-17 所示,環狀序列同樣有兩個指標,一者為前端指標,是由上層通訊軟體填入封包的指標;另一者為後端指標,是由緩衝器上取出封包發送到傳輸線上的指標。如果後端不停的將封包發送到傳輸線上,而前端又不停的填入封包,則整個環狀序列將不停的滑動,因此稱之為『滑動視窗法』(Sliding Window),傳送緩衝器也稱為『傳送視窗』(Send Window)。當然接收緩衝器也是同樣道理,前端不停的由傳輸線上接收封包;而後端也不停的傳送給上層通訊軟體,也稱之為『接收視窗』(Receive Window)。
如圖 7-17 所示(假設每個封包長度為 10 Bytes,實務上長短是不定的),當 TCP(TCP_A 或 TCP_B)欲傳送封包時,便將傳送視窗的後端指標號碼填入 seq 序號,表示目前傳送資料的順序號碼,而將接收視窗的前端指標填入 ack,表示期望對方下一次傳送的序號,並確認序號以前的資料都正常接收。
圖 7-17 傳送視窗與接收視窗
(C) 全雙工運作範例
我們用圖 7-18 來介紹一個全雙工傳輸的 TCP 連線,假設工作站 A(136.7.34.2)上執行 IE 程式,其利用 TP_A(埠口 2478)連結到工作站 B(148.34.2.6)的 Web Server,該 Web Server 連結到 TP_B(埠口 80),因此雙方所建立的連線為【136.7.34.2:2478 ←→148.34.2.6:80】。如圖中,IE 程式依序將欲傳送的資料填入 TP_A 的傳送緩衝器上,而 TP_A 也依序將資料發送到網路上。譬如,TCP_A 連續發送 4 個封包給 TCP_B(20、30、40、50),每個封包資料長度為 10 Bytes,TCP_B 接收後填入接收緩衝器,也依序傳送給 Web Server。相同的,TCP_B 由 Web Server 上拿取欲傳送的資料填入傳送緩衝器上,也依序傳送給 TCP_A,TCP_A 接收後填入接收緩衝器,再由 IE 程式取走,它們之間就是利用傳送資料時,順便攜帶 ack 訊號來確認已收到的資料,此方法又稱為『搭順風車』(Piggyback)。
圖 7-18 滑動視窗法之運作
(D) PUSH 旗號
並非所有情況下都是雙方同時傳送資料,多數的時候是單方向傳送資料,此時對方如何傳送確認的訊號?一般發送端都會將 Code PUSH 設定為 1(PSH = 1),表示希望對方接收到後,即時傳送給上層通訊軟體,並回應確認訊號。一般情況下,接收端都會視其情形來回應,如果有要傳送資料它便以搭順風車方式回應,否則另發送確認訊號(ACK & ack)給傳送端。至於會不會即時回應或傳送給上層軟體,這要看接收端的工作負荷情形,因此,在傳送端都設定有一計時器,如溢時未收到回應,將再重送一次。接收端由順序號碼可判斷是否重複接收。
(E) 錯誤控制
TCP 錯誤檢出方法是利用檢查集(Checksum)方法。傳送端發送封包之前,將封包標頭和所承載的資料以檢查集計算,得到一個檢查集數再填入封包標頭的檢查集欄位。接收端收到封包後,再以相同的方法計算所得的檢查集數是否和檢查集欄位的值相同,如果相同便回應正確(Code ACK = 1),否則回應錯誤(Code ACK = 0)要求對方重送。
7-4-3 視窗大小
視窗大小(Window Size)影響滑動視窗法的傳送速度,也代表傳送緩衝器和接收緩衝器的長度。視窗愈大表示可連續傳送的資料較多,對方也可一次確認較多的資料正常接收,但相對應的必需較長的緩衝器之記憶體空間。如果連續傳送較長的資料,而對方緩衝器不足於存放時,將會產生資料遺失的現象,因此,在雙方傳送資料之前,必需協議出緩衝器大小,也就是視窗的大小。
一般都是由接收端決定通訊的視窗大小,如圖 7-19 所示,當 TCP_A 要求建立連線時,希望的視窗大小為 4096(以 Bytes 為單位),並將 4096 的數值填入封包之視窗(Window)欄位裡(win = 4096)。TCP_B 接收到後檢查自己的緩衝器之記憶體後,發現只能提供 2048 Bytes 空間,因此將該訊息回應給 TCP_A(win = 2048)。TCP_A 再回應確認以 2048 的視窗大小傳輸資料,雙方的協議便成功。
圖 7-19 TCP 建立連線時協商視窗大小
但當接收端接收資料而來不及傳送給上層通訊軟體時,可能會快速耗損接收緩衝器,發生的原因可能是發送端傳輸過快,或上層通訊軟體處理速度過慢,造成滑動視窗滑動過慢。為了不讓傳送的資料因緩衝器爆滿而遺失,接收端必需隨時告知傳送端還有多少緩衝器可以接收資料,通知的方法是接收到回應確認時,將緩衝器空閒長度填入視窗(Window)欄位內,傳送端便可以知道對方還有多少空間可以接收資料,如同在圖 7-19 中加入 win 欄位訊號。如果傳送端發現對方視窗欄位的數值快速減少時,便必需減慢傳輸速度。甚至傳送端收到 Window = 0 的訊息,表示對方緩衝器已爆滿,而必須暫停傳送資料。因此,接收端常用此方法來要求傳送端暫停傳送資料,但也不一定是緩衝器爆滿。