三次握手(Three-way Handshake)其實就是指建立一個TCP連接時,需要客戶端和服務器總共發(fā)送3個包。
進行三次握手的主要作用就是為了確認雙方的接收能力和發(fā)送能力是否正常、指定自己的初始化序列號為后面的可靠性傳送做準備。
實質上其實就是連接服務器指定端口,建立TCP連接,并同步連接雙方的序列號和確認號,交換TCP窗口大小信息。
剛開始客戶端處于 Closed 的狀態(tài),服務端處于 Listen 狀態(tài)。
進行三次握手:
第一次握手:客戶端給服務端發(fā)一個 SYN 報文,并指明客戶端的初始化序列號 ISN©。此時客戶端處于 SYN_SEND 狀態(tài)。首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數(shù)據(jù),但要消耗掉一個序號。
第二次握手:服務器收到客戶端的 SYN 報文之后,會以自己的 SYN 報文作為應答,并且也是指定了自己的初始化序列號 ISN(s)。同時會把客戶端的 ISN + 1 作為ACK 的值,表示自己已經(jīng)收到了客戶端的 SYN,此時服務器處于 SYN_REVD 的狀態(tài)。在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y。
第三次握手:客戶端收到 SYN 報文之后,會發(fā)送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作為 ACK 的值,表示已經(jīng)收到了服務端的 SYN 報文,此時客戶端處于 ESTABLISHED 狀態(tài)。
服務器收到 ACK 報文之后,也處于 ESTABLISHED 狀態(tài),此時,雙方已建立起了連接。
確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始為seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數(shù)據(jù),不攜帶數(shù)據(jù)則不消耗序號。發(fā)送第一個SYN的一端將執(zhí)行主動打開(active open),接收這個SYN并發(fā)回下一個SYN的另一端執(zhí)行被動打開(passive open)。
在socket編程中,客戶端執(zhí)行connect()時,將觸發(fā)三次握手。