TCP連線建立和關閉中的疑難點

2021-06-01 09:39:49 字數 2395 閱讀 2525

tcp連線建立和關閉中的疑難點

近日在閱讀《unix網路程式設計》,以前在《計算機網路》課程中學到tcp,當時只是簡單了解了tcp連線建立的三次握手和關閉時的四次握手。並沒有對其中各個狀態以及其中的疑問進行深究。以下僅僅是個人的學習筆記~~

疑問1: tcp建立連線時為什麼要進行第三次握手?

疑問2: tcp關閉連線時為什麼是四次握手?

疑問3:為什麼主動關閉的一端會出現time_wait狀態?

在解答以上疑問前,先給出tcp連線建立和關閉的狀態及狀態變遷圖:

圖1  tcp正常連線建立和終止所對應的狀態

圖2  tcp的狀態變遷圖

疑問1解答:

客戶端呼叫connect進行主動開啟,並傳送syn j(j為序列號,序號用來標識從客戶端向服務端傳送的資料字節流)到服務端。在第一次握手完成後,服務端會傳送syn k和ack j+1(對客戶syn j 的確認)到客戶端,服務端此時的狀態為syn_recv,服務端會為此狀態維護乙個半連線佇列。當服務端收到客戶的確認包ack時,會在半連線佇列中刪除該條目,服務端進入established狀態。若客戶端在收到服務端的syn k和ack j+1後不再傳送ack k+1確認包,則會導致服務端未完成佇列溢位,此時服務端會給dos攻擊有機可乘。

服務端受dos攻擊的乙個重要因素是:服務端在傳送完syn+ack包後會等待客戶端的ack包,如果在一定的等待時間內未收到,服務端會進行首次重傳,等待一段時間仍未收到客戶ack包,會進行第二次重傳,直到重傳次數超過系統規定的最大值,系統將該連線資訊從半連線佇列中刪除。如果系統刪除的頻率小於半連線狀態的增長頻率,服務端就無法正常提供服務。

如果是設計成兩次握手,就有可能是被連線方第一次發出ack訊息後,就處於成功建立連線的狀態,但這條訊息丟失了,主動連線方因為沒有收到這個ack訊息會認為建立連線失敗,也許會放棄連線或啟動新的連線,但被連線方會一直監聽那個它誤認為成功的連線。採用三次握手,前兩次握手任何一次失敗都會導致連線雙方都處於未連線狀態,第三次失敗只會導致連線方處於成功狀態,但做主動連線方,肯定會在連線不久後通過這個連線傳送資料,這樣就可以利用這個機制做進一步的容錯。

疑問2解答:

tcp關閉連線時為什麼是四次握手?這是由於tcp半關閉(harf-close)造成的(所謂的半關閉tcp提供了連線的一端在結束它的傳送後還能接收來自另一端資料的能力。例如在tcp關閉連線步驟2和步驟3之間可以有從執行被動關閉端到執行主動關閉端的資料流)。tcp連線是全雙工(即連線的雙方既可以接收資料也可以傳送資料),因此每個方向必須單獨地進行關閉。即一方傳送乙個fin,另一方收到後傳送乙個ack,這就是所謂的四次握手了。其實四次握手並非絕對的,只是一般而言。因為有時步驟1的fin隨資料一起傳送,另外,執行被動關閉的一端在步驟2和3發出的ack和fin也可以合併成乙個位元組同時傳送。

疑問3解答:

為什麼主動關閉的一端會出現time_wait狀態?

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

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

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

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

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

後記:tcp連線的三次握手有可能遭受拒絕服務攻擊(syn-flooding) ,而且tcp連線關閉時的time_wait狀態保持整個連線的做法似乎不是很好。 tcp的這兩個缺點可以由sctp來規避~感興趣的讀者可以參考閱讀《unix網路程式設計》第二章之sctp關聯的建立和終止。

TCP建立和關閉連線

一 建立連線 1 請求端 通常稱為客戶 傳送乙個 s y n段指明客戶打算連線的伺服器的埠,以及初 始序號 i s n,在這個例子中為1 4 1 5 5 3 1 5 2 1 這個s y n段為報文段1。2 伺服器發回包含伺服器的初始序號的s y n報文段 報文段2 作為應答。同時,將確認 序號設定為...

TCP連線建立和釋放

cp是面向連線的運輸層協議,它提供可靠交付的 全雙工的 面向位元組流的點對點服務。http協議便是基於tcp協議實現的。雖然作為應用層協議,http協議並沒有明確要求必須使用tcp協議作為運輸層協議,但是因為http協議對可靠性的的要求,預設http是基於tcp協議的。若是使用udp這種不可靠的 盡...

TCP 連線的建立和終止

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