(1)三次握手
三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務器總共發送3個包。進行三次握手的主要作用就是為了確認雙方的接收能力和發送能力是否正常、指定自己的初始化序列號為后面的可靠性傳送做準備。實質上其實就是連接服務器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號,交換TCP窗口大小信息。
剛開始客戶端處于 Closed 的狀態,服務端處于 Listen 狀態。
第一次握手:客戶端給服務端發一個 SYN 報文,并指明客戶端的初始化序列號 ISN,此時客戶端處于 SYN_SEND 狀態。
首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數據,但要消耗掉一個序號。
第二次握手:服務器收到客戶端的 SYN 報文之后,會以自己的 SYN 報文作為應答,并且也是指定了自己的初始化序列號 ISN。同時會把客戶端的 ISN + 1 作為ACK 的值,表示自己已經收到了客戶端的 SYN,此時服務器處于 SYN_REVD 的狀態。
在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y
第三次握手:客戶端收到 SYN 報文之后,會發送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作為 ACK 的值,表示已經收到了服務端的 SYN 報文,此時客戶端處于 ESTABLISHED 狀態。服務器收到 ACK 報文之后,也處于 ESTABLISHED 狀態,此時,雙方已建立起了連接。
確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始為seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數據,不攜帶數據則不消耗序號。
那為什么要三次握手呢?兩次不行嗎?
為了確認雙方的接收能力和發送能力都正常
如果是用兩次握手,則會出現下面這種情況:
如客戶端發出連接請求,但因連接請求報文丟失而未收到確認,于是客戶端再重傳一次連接請求。后來收到了確認,建立了連接。數據傳輸完畢后,就釋放了連接,客戶端共發出了兩個連接請求報文段,其中第一個丟失,第二個到達了服務端,但是第一個丟失的報文段只是在某些網絡結點長時間滯留了,延誤到連接釋放以后的某個時間才到達服務端,此時服務端誤認為客戶端又發出一次新的連接請求,于是就向客戶端發出確認報文段,同意建立連接,不采用三次握手,只要服務端發出確認,就建立新的連接了,此時客戶端忽略服務端發來的確認,也不發送數據,則服務端一致等待客戶端發送數據,浪費資源。
簡單來說就是以下三步:
第一次握手: 客戶端向服務端發送連接請求報文段。該報文段中包含自身的數據通訊初始序號。請求發送后,客戶端便進入 SYN-SENT 狀態。
第二次握手: 服務端收到連接請求報文段后,如果同意連接,則會發送一個應答,該應答中也會包含自身的數據通訊初始序號,發送完成后便進入 SYN-RECEIVED 狀態。
第三次握手: 當客戶端收到連接同意的應答后,還要向服務端發送一個確認報文。客戶端發完這個報文段后便進入 ESTABLISHED 狀態,服務端收到這個應答后也進入 ESTABLISHED 狀態,此時連接建立成功。
TCP 三次握手的建立連接的過程就是相互確認初始序號的過程,告訴對方,什么樣序號的報文段能夠被正確接收。 第三次握手的作用是客戶端對服務器端的初始序號的確認。如果只使用兩次握手,那么服務器就沒有辦法知道自己的序號是否 已被確認。同時這樣也是為了防止失效的請求報文段被服務器接收,而出現錯誤的情況。
(2)四次揮手