一:TCP的三次握手
建立TCP需要三次握手:客戶端傳送連線請求,伺服器確認,客戶端再次確認。
第一次握手:客戶端傳送連線請求,該TCP請求的首部,SYN標誌位1,並且隨機產生一個seq=x,並將該資料包傳送給Server。
第二次握手:伺服器迴應,Server收到資料包後由標誌位SYN=1知道Client請求建立連線,Server將標誌位SYN和ACK都置為1,ack=x+1,隨機產生一個seq=y,並將該資料包傳送給Client確認連線請求。
第三次握手:客戶端確認,若接受到的ACK=1且ack是x+1,那麼傳送ACK=1,ack number為伺服器的seq = y+1。
二:為什麼TCP連線需要三次握手,兩次為什麼不可以
防止實效的連結請求報文段被伺服器接收,從而造成服務端資源的浪費。
失效的連結請求:若客服端向服務端傳送的連線請求丟失,客戶端等待應答超時後就會再次傳送連線請求,此時,上一個連線請求就是失效的。
若建立連線只需兩次握手,客戶端並沒有太大的變化,仍然需要獲得服務端的應答後才進入ESTABLISHED狀態,而服務端在收到連線請求後就進入ESTABLISHED狀態。此時如果網路擁塞,客戶端傳送的連線請求遲遲到不了服務端,客戶端便超時重發請求,如果服務端正確接收並確認應答,雙方便開始通訊,通訊結束後釋放連線。此時,如果那個失效的連線請求抵達了服務端,由於只有兩次握手,服務端收到請求就會進入ESTABLISHED狀態,等待傳送資料或主動傳送資料。但此時的客戶端早已進入CLOSED狀態,服務端將會一直等待下去,這樣浪費服務端連線資源。
此外3次是雙方都回復ack條件下的最少次數,減少網路控制資料量。sctp(流控制傳輸協議),hip(主機標誌)等協議使用4次握手,增加cookie傳遞,防止syn攻擊。
三:TCP的四次揮手
斷開連線需要四次揮手。我們知道,TCP連線是雙向的,因此在四次揮手中,前兩次揮手用於斷開一個方向的連線,後兩次揮手用於斷開另一方向的連線,任意一方都可以要求斷開連線。
第一次揮手:主動關閉方傳送一個FIN,用來關閉主動方到被動關閉方的資料傳送,也就是主動關閉方告訴被動關閉方:我已經不會再給你發資料了(當然,在fin包之前傳送出去的資料,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些資料),但是,此時主動關閉方還可以接受資料。
第二次揮手:被動關閉方收到FIN包後,傳送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN佔用一個序號)。
第三次揮手:被動關閉方傳送一個FIN,用來關閉被動關閉方到主動關閉方的資料傳送,也就是告訴主動關閉方,我的資料也傳送完了,不會再給你發資料了。
第四次揮手:主動關閉方收到FIN後,傳送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。
四:為什麼建立連線需要三次而斷開連線需要四次
對於斷開連線,考慮TCP是全雙工的,雙方同時可以傳送和接收。第一次揮手錶示客戶端不再傳送了。第二次揮手錶示伺服器知道你不傳送了,所以伺服器就不接收了,但是伺服器可能還需要傳送,所以客戶端不能一次性把傳送和接收都關閉了,需要等著伺服器也不傳送了(第三次揮手)才能把接收也關閉了(第四次揮手)