天天看點

《UNIX網絡程式設計 卷1:套接字聯網API(第3版)》——2.4 傳輸控制協定(TCP)

本節書摘來自異步社群《unix網絡程式設計 卷1:套接字聯網api(第3版)》一書中的第2章,第2.4節,作者:【美】w. richard stevens , bill fenner , andrew m. rudoff著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

由tcp向應用程序提供的服務不同于由udp提供的服務。tcp在rfc 793[poste1 ]中有詳細說明,然後由rfc 1323[jacobson, braden, and borman 1992]、rfc 2581[allman, paxson, and stevens 1999]、rfc 2988[paxson and allman 2000]和rfc 3390[allman, floyd, and partridge 2002]加以更新。首先,tcp提供客戶與伺服器之間的連接配接(connection)。tcp客戶先與某個給定伺服器建立一個連接配接,再跨該連接配接與那個伺服器交換資料,然後終止這個連接配接。

其次,tcp還提供了可靠性(reliability)。當tcp向另一端發送資料時,它要求對端傳回一個确認。如果沒有收到确認,tcp就自動重傳資料并等待更長時間。在數次重傳失敗後,tcp才放棄,如此在嘗試發送資料上所花的總時間一般為4~10分鐘(依賴于具體實作)。

注意,tcp并不保證資料一定會被對方端點接收,因為這是不可能做到的。如果有可能,tcp就把資料遞送到對方端點,否則就(通過放棄重傳并中斷連接配接這一手段)通知使用者。這麼說來,tcp也不能被描述成是100%可靠的協定,它提供的是資料的可靠遞送或故障的可靠通知。

tcp含有用于動态估算客戶和伺服器之間的往返時間(round-trip time,rtt)的算法,以便它知道等待一個确認需要多少時間。舉例來說,rtt在一個區域網路上大約是幾毫秒,跨越一個廣域網則可能是數秒鐘。另外,因為rtt受網絡流通各種變化因素影響,tcp還持續估算一個給定連接配接的rtt。

tcp通過給其中每個位元組關聯一個序列号對所發送的資料進行排序(sequencing)。舉例來說,假設一個應用寫2048位元組到一個tcp套接字,導緻tcp發送2個分節:第一個分節所含資料的序列号為1~1024,第二個分節所含資料的序列号為1025~2048。(分節是tcp傳遞給ip的資料單元。)如果這些分節非順序到達,接收端tcp将先根據它們的序列号重新排序,再把結果資料傳遞給接收應用。如果接收端tcp接收到來自對端的重複資料(譬如說對端認為一個分節已丢失并是以重傳,而這個分節并沒有真正丢失,隻是網絡通信過于擁擠),它可以(根據序列号)判定資料是重複的,進而丢棄重複資料。

udp不提供可靠性。udp本身不提供确認、序列号、rtt估算、逾時和重傳等機制。如果一個udp資料報在網絡中被複制,兩份副本就可能都遞送到接收端的主機。同樣地,如果一個udp客戶發送兩個資料報到同一個目的地,它們可能被網絡重新排序,颠倒順序後到達目的地。udp應用必須處理所有這些情況,在22.5節中我們将展示如何處理。

再次,tcp提供流量控制(flow control)。tcp總是告知對端在任何時刻它一次能夠從對端接收多少位元組的資料,這稱為通告視窗(advertised window)。在任何時刻,該視窗指出接收緩沖區中目前可用的空間量,進而確定發送端發送的資料不會使接收緩沖區溢出。該視窗時刻動态變化:當接收到來自發送端的資料時,視窗大小就減小,但是當接收端應用從緩沖區中讀取資料時,視窗大小就增大。通告視窗大小減小到0是有可能的:當tcp對應某個套接字的接收緩沖區已滿,導緻它必須等待應用從該緩沖區讀取資料時,方能從對端再接收資料。

udp不提供流量控制。如我們将在8.13節所示,讓較快的udp發送端以一個udp接收端難以跟上的速率發送資料報是非常容易的。

最後,tcp連接配接是全雙工的(full-duplex)。這意味着在一個給定的連接配接上應用可以在任何時刻在進出兩個方向上既發送資料又接收資料。是以,tcp必須為每個資料流方向跟蹤諸如序列号和通告視窗大小等狀态資訊。建立一個全雙工連接配接後,需要的話可以把它轉換成一個單工連接配接(見6.6節)。

udp可以是全雙工的。

繼續閱讀