第一次握手:建立連接時(shí)踏幻,客戶(hù)端發(fā)送syn包(syn=j)到服務(wù)器枷颊,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);SYN:同步序列編號(hào)(Synchronize Sequence Numbers)夭苗。
第二次握手:服務(wù)器收到syn包信卡,必須確認(rèn)客戶(hù)的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k)题造,即SYN+ACK包傍菇,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);
第三次握手:客戶(hù)端收到服務(wù)器的SYN+ACK包界赔,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1)丢习,此包發(fā)送完畢,客戶(hù)端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài)淮悼,完成三次握手咐低。
完成三次握手,客戶(hù)端與服務(wù)器開(kāi)始傳送數(shù)據(jù)敛惊,在上述過(guò)程中渊鞋,還有一些重要的概念:
未連接隊(duì)列
在三次握手協(xié)議中,服務(wù)器維護(hù)一個(gè)未連接隊(duì)列瞧挤,該隊(duì)列為每個(gè)客戶(hù)端的SYN包(syn=j)開(kāi)設(shè)一個(gè)條目,該條目表明服務(wù)器已收到SYN包儡湾,并向客戶(hù)發(fā)出確認(rèn)特恬,正在等待客戶(hù)的確認(rèn)包。這些條目所標(biāo)識(shí)的連接在服務(wù)器處于SYN_RECV狀態(tài)徐钠,當(dāng)服務(wù)器收到客戶(hù)的確認(rèn)包時(shí)癌刽,刪除該條目,服務(wù)器進(jìn)入ESTABLISHED狀態(tài)
關(guān)閉TCP連接:改進(jìn)的三次握手
對(duì)于一個(gè)已經(jīng)建立的連接尝丐,TCP使用改進(jìn)的三次握手來(lái)釋放連接(使用一個(gè)帶有FIN附加標(biāo)記的報(bào)文段)显拜。TCP關(guān)閉連接的步驟如下:
第一步,當(dāng)主機(jī)A的應(yīng)用程序通知TCP數(shù)據(jù)已經(jīng)發(fā)送完畢時(shí)爹袁,TCP向主機(jī)B發(fā)送一個(gè)帶有FIN附加標(biāo)記的報(bào)文段(FIN表示英文finish)远荠。
第二步,主機(jī)B收到這個(gè)FIN報(bào)文段之后失息,并不立即用FIN報(bào)文段回復(fù)主機(jī)A譬淳,而是先向主機(jī)A發(fā)送一個(gè)確認(rèn)序號(hào)ACK,同時(shí)通知自己相應(yīng)的應(yīng)用程序:對(duì)方要求關(guān)閉連接(先發(fā)送ACK的目的是為了防止在這段時(shí)間內(nèi)盹兢,對(duì)方重傳FIN報(bào)文段)邻梆。
第三步,主機(jī)B的應(yīng)用程序告訴TCP:我要徹底的關(guān)閉連接绎秒,TCP向主機(jī)A送一個(gè)FIN報(bào)文段浦妄。
第四步,主機(jī)A收到這個(gè)FIN報(bào)文段后,向主機(jī)B發(fā)送一個(gè)ACK表示連接徹底釋放剂娄。
為什么要采用三次握手蠢涝,兩次不行嗎?
為什么連接的時(shí)候是三次握手宜咒,關(guān)閉的時(shí)候卻是四次握手惠赫?
答:因?yàn)楫?dāng)Server端收到Client端的SYN連接請(qǐng)求報(bào)文后,可以直接發(fā)送SYN+ACK報(bào)文故黑。其中ACK報(bào)文是用來(lái)應(yīng)答的儿咱,SYN報(bào)文是用來(lái)同步的。但是關(guān)閉連接時(shí)场晶,當(dāng)Server端收到FIN報(bào)文時(shí)混埠,很可能并不會(huì)立即關(guān)閉SOCKET,所以只能先回復(fù)一個(gè)ACK報(bào)文诗轻,告訴Client端钳宪,"你發(fā)的FIN報(bào)文我收到了"。只有等到我Server端所有的報(bào)文都發(fā)送完了扳炬,我才能發(fā)送FIN報(bào)文吏颖,因此不能一起發(fā)送。故需要四步握手恨樟。
轉(zhuǎn)載出處:https://blog.csdn.net/qq_18425655/article/details/52163228