TCP的連線建立

weixin_33935777發表於2017-10-16

TCP建立連線的過程叫做握手。握手需要在客戶和伺服器之間交換三個TCP報文段。

嘉定主機A執行的是TCP客戶程式,而B執行的是TCP伺服器程式。最初兩端的TCP程式都屬於關閉狀態。假設:A主動開啟連結,B被動開啟連結。

一開始,B的TCP伺服器程式先建立傳輸控制塊,準備接受客戶程式的連線請求。然後伺服器程式就處於收聽狀態,等待客戶的連線請求。如有就做出響應。

A的客戶程式也是首先建立傳輸控制塊TCP。然後,在打算建立TCP連線時,向B發出連線請求報文段,這時首部中的同部位SYN = 1,同時選擇一個初始序號seq = x,TCP規定,SYN報文段不能攜帶資料,但要消耗掉一個序號。這時TCP客戶程式進入同步已傳送狀態。

B收到連線請求報文段後,如同意建立連線,則向A傳送確認。在確認報文段中應把SYN位和ACK為都置為1,確認號是ack = x + 1,同時也為自己選擇一個初始序號seq = y.請注意,這個報文段也不能懈怠資料,但是同樣要消耗掉一個序號。這是伺服器程式進入同步收到狀態。

TCP客戶程式在收到B的確認後,還要給B給出確認。確認報文段的ACK = 1,確認號ack = y + 1,而自己的序號seq = x + 1。TCP的標準規定,ACK報文段可以攜帶資料,但是如果不攜帶資料則不消耗序號。在這種情況下,下一個資料包文段的序號仍是seq = x + 1。這時,TCP的連線已經建立,A進入已建立連線狀態。

當B收到A的確認後,進入已建立連線狀態。

為什麼A最後還要傳送一次確認呢?這主要是為了防止已失效的連線請求報文段突然又傳送到了B,因而產生錯誤。

所謂“已失效的連線請求報文段”是這樣產生的。考慮一種正常情況,A發出連線請求,但因連線請求報文丟失而未確認。於是A重新傳送一次連線請求。後來收到了確認,建立了連線。資料傳輸完畢後就釋放了連線。A共傳送了兩個連線請求報文段,其中一次丟失,第二次到達了B。沒有已丟失的連線報文段。

現在嘉定出現一種異常情況,即A發出的第一個請求報文段並沒有丟失,而是在某些網路節點長時間滯留了,以致延誤到連線釋放以後的某個時間才到達B。本來這事一個早已失效的報文段。但是B收到此失效的連線報文請求後,就誤認為是A發出的一次新的連線請求。於是就向A發出了確認報文段,同意簡歷連線。假定不採用報文握手,那麼只要B發出確認新的連線已經建立了。

由於現在A並沒有建立連線的請求,因此不會理睬A的確認,也不會向B傳送資料。但是B卻以為新的運輸連結已經建立連線了,並一直等待A發來資料。B的許多資源就這樣白白浪費了。

採用三報文握手的辦法,可以放置上述現象發生。例如在剛才的異常情況下,A不會向B的確認發出確認。B由於收不到確認,就知道A並沒有要求建立連線。

相關文章