三次握手
- 第一次握手:
客戶端發送syn包(syn=x)到服務器,並進入SYN_SEND狀態,等待服務器確認;
- 第二次握手:
服務器收到syn包,必須確認客戶的SYN(ack=x+1),同時自己也發送一個SYN包(syn=y),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
- 第三次握手:
客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=y+1),此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。
握手過程中傳送的包里不包含數據,三次握手完畢后,客戶端與服務器才正式開始傳送數據。理想狀態下,TCP連接一旦建立,在通信雙方中的任何一方主動關閉連接之前,TCP 連接都將被一直保持下去。
三次握手的最主要目的是保證連接是雙工的,可靠更多的是通過重傳機制來保證的。
為了保證服務端能收接受到客戶端的信息並能做出正確的應答而進行前兩次(第一次和第二次)握手,為了保證客戶端能夠接收到服務端的信息並能做出正確的應答而進行后兩次(第二次和第三次)握手。
為什么要進行三次握手,不是二次握手
謝希仁版《計算機網絡》中的例子:
"已失效的連接請求報文段”的產生在這樣一種情況下:
client發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達server。
本來這是一個早已失效的報文段,但server收到此失效的連接請求報文段后,就誤認為是client再次發出的一個新的連接請求。
於是就向client發出確認報文段,同意建立連接。假設不采用“三次握手”,那么只要server發出確認,新的連接就建立了。
由於現在client並沒有發出建立連接的請求,因此不會理睬server的確認,也不會向server發送數據,但server卻以為新的運輸連接已經建立,並一直等待client發來數據。
這樣,server的很多資源就白白浪費掉了。
采用“三次握手”的辦法可以防止上述現象發生。
例如剛才那種情況,client不會向server的確認發出確認,server由於收不到確認,就知道client並沒有要求建立連接。”
這個例子很清晰的闡釋了“三次握手”對於建立可靠連接的意義。
四次揮手
與建立連接的“三次握手”類似,斷開一個TCP連接則需要“四次握手”。
- 第一次揮手
主動關閉方發送一個FIN,用來關閉主動方到被動關閉方的數據傳送,也就是主動關閉方告訴被動關閉方:我已經不 會再給你發數據了(當然,在fin包之前發送出去的數據,如果沒有收到對應的ack確認報文,主動關閉方依然會重發這些數據),但是,此時主動關閉方還可 以接受數據。
- 第二次揮手
被動關閉方收到FIN包后,發送一個ACK給對方,確認序號為收到序號+1(與SYN相同,一個FIN占用一個序號)。
- 第三次揮手
被動關閉方發送一個FIN,用來關閉被動關閉方到主動關閉方的數據傳送,也就是告訴主動關閉方,我的數據也發送完了,不會再給你發數據了。
- 第四次揮手
主動關閉方收到FIN后,發送一個ACK給被動關閉方,確認序號為收到序號+1,至此,完成四次揮手。