TCP 連線的建立和終止

2021-09-09 01:16:36 字數 3981 閱讀 9782

三路握手

建立乙個tcp連線時會發生下述情形。

(1)伺服器必須準備好接受外來的連線。這通常通過呼叫socket、bind和listen這3個函式來完成的,我們稱之為被動開啟。

(2)客戶通過呼叫connect發起主動開啟。這導致客戶tcp傳送乙個syn(同步)分節,它告訴伺服器客戶將在(待建立的)連線中傳送的資料的初始序列號。通常syn分節不攜帶資料,其所在ip資料報只含有乙個ip首部、乙個tcp首部及可能有的tcp選項。

(3)伺服器必須確認(ack)客戶的syn,同時自己也得傳送乙個syn分節,它含有伺服器將在同一連線中傳送的資料的初始序列號。伺服器在單個分節中傳送syn和對客戶syn的ack(確認)。

(4)客戶必須確認伺服器的syn。

這樣交換至少需要3個分組,因此稱之為tcp的三路握手。圖2-2展示了所交換的3個分節。

圖2-2給出的客戶的初始序列號為j,伺服器的初始序列號為k。ack中的確認號是傳送這個ack的一端所期待的下乙個序列號。因為syn佔據乙個位元組的序列號空間,所以每乙個syn的ack中的確認號就是該syn的初始序列號加1。類似地,每乙個fin(表示結束)的ack中的確認號為該fin的序列號加1.

tcp選項

每乙個syn可以含有多個tcp選項。下面是常用的tcp選項。

tcp 連線終止

tcp建立乙個連線需3個分節,終止乙個連線則需要4個分節。

(1)某個應用程序首先呼叫close,我們稱該端執行主動關閉。該端的tcp於是傳送乙個fin分節,表示資料傳送完畢。

(2)接收到這個fin的對端執行被動關閉。這個fin由tcp確認。它的接收也作為乙個檔案結束符傳遞給接收端應用程序,因為fin的接收意味著接收端應用程序在相應連線上再無額外資料可接收。

(3)一段時間後,接收到這個檔案結束符的應用程序將呼叫close關閉它的套接字。這導致它的tcp也傳送乙個fin。

(4)接收這個最終fin的原傳送端tcp確認這個fin。

既然每個方向都需要乙個fin和乙個ack,因此通常需要4個分節。我們使用限定詞「通常」是因為:某些情形下步驟1的fin隨資料一起傳送;另外,步驟2和步驟3傳送的分節都出自執行被動關閉那一端,有可能被合併成乙個分節。圖2-3展示了這些分組。

類似syn,乙個fin也佔據1個位元組的序列號空間。因此,每個fin的ack確認號就是這個fin的序列號加1.

在步驟2和步驟3之間,從執行被動關閉一端到執行主動關閉一端流動資料是可能的。這稱為半關閉。

當套接字被關閉時,其所在端tcp各自傳送乙個fin。我們在圖中指出,這是由應用程序呼叫close而發生的,不過需認識到,當乙個unix程序無論自願地(呼叫exit或從main函式返回)還是非自願地(收到乙個終止本程序的訊號)終止時,所以開啟的描述符都被關閉,這也是導致仍然開啟的任何tcp連線上也發出乙個fin。

圖2-3展示了客戶執行主動關閉的情形,不過我們指出,無論是客戶還是伺服器,任何一端都可以執行主動關閉。通常情況是客戶執行主動關閉,但是某些協議卻是由伺服器執行主動關閉。

tcp狀態轉換圖

tcp涉及連線建立和連線終止的操作可以用狀態轉換圖來說明,如圖2-4所示。

tcp為乙個連線定義了11種狀態,並且tcp規則規定如何基於當前狀態及在該狀態下所接收的分節從乙個狀態轉換到另乙個狀態。舉例來說,當某個應用程序在closed狀態下執行主動開啟時,tcp將發生乙個syn,且新的狀態是syn_sent。如果這個tcp接著接收到乙個帶ack的syn,它將傳送乙個ack,且新的狀態是established。這個最終狀態是絕大多數資料傳送發生的狀態。

自established狀態引出的兩個箭頭處理連線的終止。如果某個應用程序在接收到乙個fin之前呼叫close(主動關閉),那就轉換到fin_wait_1狀態。但如果某個應用程序在established狀態期間接收到乙個fin(被動關閉),那就轉換到close_wait狀態。

我們用粗實現表示通常的客戶狀態的轉換,用粗虛線表示通常的服務狀態轉換。圖中還註明存在兩個我們未曾討論的轉換:乙個同時開啟,發生在兩端幾乎同時傳送syn並且這兩個syn在網路中交錯的情形下,另乙個為同時關閉,發生在兩端幾乎同時傳送fin的情形下。

觀察分組

圖2-5展示乙個完整的tcp連線所發生的實際分組交換情況,包括連線建立、資料傳送和連線終止3個階段。圖中還展示了每個端點所歷經的tcp狀態。

本例中的客戶通告乙個值為536的mss(表明該客戶只實現了最小重組緩衝區大小),伺服器通告乙個值為1460(乙太網上ipv4的典型值)。不同方向上mss值不相同不成問題。

一旦建立乙個連線,客戶就構造乙個請求並傳送給伺服器。這裡我們假設該請求適合於單個tcp分節(即請求大小小於伺服器通告的值為1460位元組的mss)。伺服器處理該請求並傳送乙個應答,我們假設該應答也適合當個分節(本例小於536位元組)。圖中使用粗箭頭表示這兩個資料分節。注意,伺服器對客戶請求的確認是伴隨其應答傳送的。這種做法稱為捎帶,它通常在伺服器處理請求並產生應答的時間少於200ms時傳送。如果伺服器耗用更長時間,譬如1s,那麼我們將看到先是確認後是應答。

圖中隨後展示的是終止連線的4個分節。注意,執行主動關閉的那一端(本例子中為客戶)進入time_wait狀態。

圖2-5中值得注意的是,如果該連線的整個目的僅僅是傳送乙個單分節的請求和接受乙個單分節的應答,那麼使用tcp有8個分節的開銷。如果改用udp,那麼只需交換兩個分組:乙個承載請求,乙個承載應答。然而從tcp切換到udp將喪失tcp提供給應用程序的全部可靠性,迫使可靠服務的一大堆細節從傳輸層轉移到應用程序。tcp提供的另乙個重要特性及擁塞控制也必須由udp應用程序來處理。儘管如此,我們仍然需要知道許多網路應用是使用udp構建的,因為它們需要交換的資料量較少,而udp避免了tcp連線建立和終止所需的開銷。

time_wait 狀態

在圖2-4中我們看到執行主動關閉的那端經歷了這個狀態。該端點停留在這個狀態的持續時間是最長分節生命期的兩倍,有時稱之為2msl。

time_wait狀態有兩個存在的理由:

(1)可靠地實現tcp全雙工連線的終止;

(2)允許老的重複分節在網路中消逝。

第乙個理由可以通過檢視圖2-5並假設最終的ack丟失了來解釋。伺服器將重新傳送它的最終那個fin,因此客戶必須維護狀態資訊,以允許它重新傳送那個ack。要是客戶不維護狀態資訊,它將響應以乙個rst(另外一種型別的tcp分節),該分節將被伺服器解釋成乙個錯誤。如果tcp打算執行所有必要的工作以徹底終止某個連線上兩個方向上的資料流(即全雙工關閉),那麼它必須正確處理連線終止序列4個分節中任何乙個分節丟失的情況。本例子也說明了為什麼執行主動關閉的那一端是處於time_wait狀態的那一端:因為可能不得不重傳最終那個ack的就是那一端。

為理解存在time_wait狀態的第二個理由,我們假設在12.106.32.154的1500埠和206.168.112.219的21埠之間有乙個tcp連線。我們關閉這個連線,過一段時間後在相同的ip位址和埠直接建立另乙個連線。後乙個連線稱為前乙個連線的化身,因為它們的ip位址和埠號都相同。tcp必須防止來自某個連線的老的重複分組在該連線已終止後再現,從而被誤解成屬於同一連線的某個新的化身。為做到這一點,tcp將不給處於time_wait狀態的連線發起新的化身。既然time_wait狀態的持續時間是msl的2倍,這就足以讓某個方向上的分組最多存活msl秒即被丟棄,另乙個方向上的應答最多存活msl秒也被丟棄。通過實施這個規則,我們就能保證每成功建立乙個tcp連線時,來自該連線先前化身的老的重複分組都已在網路中消逝了。

TCP 連線的建立和終止

1.伺服器通過呼叫socket,bind和listen三個函式準備接受外來連線,稱為被動開啟。2.客戶通過呼叫connect發起主動開啟,導致客戶tcp傳送乙個syn同步分節,告訴伺服器將在連線中傳送的資料的初始序列號。syn分節不包含資料,只包含乙個ip首部,乙個tcp首部及可能的tcp選項。3....

TCP連線的建立和終止

一 tcp連線建立 三路握手 1 伺服器必現準備好接受外來的連線,即被動開啟。2 客戶通過呼叫connect發起主動開啟,這導致客戶tcp傳送乙個syn分節,它告訴伺服器客戶將在連線中傳送的資料的初始序列號。3 伺服器必須確認 ack 客戶的syn,同時自己也得傳送乙個syn分節,它含有伺服器將在同...

TCP連線建立和終止小結

如圖 1.請求端傳送乙個syn到伺服器的相應埠,以及初始序號isn 2.伺服器傳送包含伺服器的初始序號的syn作為應答,同時確認序號設定為客戶的isn 1 3.客戶將確認序號設定為伺服器的isn 1 最大報文段長度 mss 同時開啟 一般情況下,連線建立時是一方傳送syn,另一方傳送syn ack,...