TCP連接的建立與關(guān)閉過(guò)程可以概括為“三次握手,四次揮手”,但是具體的過(guò)程還是很復(fù)雜,也很難記住,就寫(xiě)下來(lái)幫助記憶吧。
先看圖片

這是《圖解TCP_IP》的一張圖,很簡(jiǎn)單,但是沒(méi)有具體的過(guò)程和狀態(tài)轉(zhuǎn)換。

這張圖比較詳細(xì),就針對(duì)這張圖詳細(xì)分析一下TCP的狀態(tài)轉(zhuǎn)換,實(shí)線代表客戶端,虛線代表服務(wù)器。
建立連接過(guò)程分析
第一次握手:建立連接時(shí),客戶端到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);SYN:同步序列編號(hào)(Synchronize Sequence Numbers)。這里注意:請(qǐng)求建立連接的一般都是客戶端程序,而服務(wù)器空閑時(shí)處于LISTEN狀態(tài)。
第二次握手
服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=j+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=k),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);RST:表示出現(xiàn)異常要強(qiáng)制斷開(kāi)連接。這里貼出全部8個(gè)控制位及其含義。

第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。
TCP連接建立過(guò)程總結(jié)
客戶端狀態(tài):發(fā)送syn進(jìn)入SYN_SENT→接收SYN,ACK并發(fā)送ACK進(jìn)入ESTABLISHED狀態(tài)。
服務(wù)器狀態(tài):接受SYN發(fā)送SYN,ACK進(jìn)入SYN_RCVD→接收ACK進(jìn)入ESTABLISHED狀態(tài)或接受RST斷開(kāi)連接。
關(guān)閉連接過(guò)程分析
第一次揮手:主動(dòng)關(guān)閉方發(fā)送一個(gè)FIN進(jìn)入FIN_WAIT_1,用來(lái)關(guān)閉主動(dòng)方到被動(dòng)關(guān)閉方的數(shù)據(jù)傳送,也就是主動(dòng)關(guān)閉方告訴被動(dòng)關(guān)閉方:我已經(jīng)不 會(huì)再給你發(fā)數(shù)據(jù)了(當(dāng)然,在fin包之前發(fā)送出去的數(shù)據(jù),如果沒(méi)有收到對(duì)應(yīng)的ack確認(rèn)報(bào)文,主動(dòng)關(guān)閉方依然會(huì)重發(fā)這些數(shù)據(jù)),但是,此時(shí)主動(dòng)關(guān)閉方還可以接受數(shù)據(jù)。
第二次揮手:被動(dòng)關(guān)閉方收到FIN包后,發(fā)送一個(gè)ACK給對(duì)方,確認(rèn)序號(hào)為收到序號(hào)+1(與SYN相同,一個(gè)FIN占用一個(gè)序號(hào))。
第三次揮手:被動(dòng)關(guān)閉方發(fā)送一個(gè)FIN,用來(lái)關(guān)閉被動(dòng)關(guān)閉方到主動(dòng)關(guān)閉方的數(shù)據(jù)傳送,也就是告訴主動(dòng)關(guān)閉方,我的數(shù)據(jù)也發(fā)送完了,不會(huì)再給你發(fā)數(shù)據(jù)了。
第四次揮手:主動(dòng)關(guān)閉方收到FIN后,發(fā)送一個(gè)ACK給被動(dòng)關(guān)閉方,確認(rèn)序號(hào)為收到序號(hào)+1,至此,完成四次揮手。
注意:1.設(shè)置2MSL超時(shí)的原因:如果直接關(guān)閉,而服務(wù)器沒(méi)有接收到最后一個(gè)ACK,服務(wù)器會(huì)重發(fā)FIN,此時(shí)客戶端已經(jīng)關(guān)閉,服務(wù)器會(huì)認(rèn)為連接發(fā)生錯(cuò)誤,而事實(shí)上此時(shí)已經(jīng)客戶端已經(jīng)正確關(guān)閉。
2.FIN_WAIT_2狀態(tài)不一定進(jìn)入。服務(wù)器和客戶端可能同時(shí)關(guān)閉,不進(jìn)入FIN_WAIT_2狀態(tài)。
關(guān)閉連接總結(jié)
客戶端:發(fā)送FIN進(jìn)入FIN_WAIT_1狀態(tài)客(客戶端停止發(fā)送數(shù)據(jù))→不同時(shí)關(guān)閉則接受ACK進(jìn)入FIN_WAIT_2等待服務(wù)器關(guān)閉(或同時(shí)關(guān)閉進(jìn)入TIME_WAIT)→接受到服務(wù)器發(fā)送的FIN進(jìn)入TIME_WAIT(服務(wù)器停止發(fā)送數(shù)據(jù))→等待2MSL→CLOSED
服務(wù)器:接受FIN發(fā)送ACK進(jìn)入CLOSE_WAIT→發(fā)送FIN等待ACK進(jìn)入LAST_ACK→接收ACK進(jìn)入CLOSED
其他問(wèn)題
(??途W(wǎng))
TCP的三次握手過(guò)程?為什么會(huì)采用三次握手,若采用二次握手可以嗎?
答:建立連接的過(guò)程是利用客戶服務(wù)器模式,假設(shè)主機(jī)A為客戶端,主機(jī)B為服務(wù)器端。
(1)TCP的三次握手過(guò)程:主機(jī)A向B發(fā)送連接請(qǐng)求;主機(jī)B對(duì)收到的主機(jī)A的報(bào)文段進(jìn)行確認(rèn);主機(jī)A再次對(duì)主機(jī)B的確認(rèn)進(jìn)行確認(rèn)。
(2)采用三次握手是為了防止失效的連接請(qǐng)求報(bào)文段突然又傳送到主機(jī)B,因而產(chǎn)生錯(cuò)誤。失效的連接請(qǐng)求報(bào)文段是指:主機(jī)A發(fā)出的連接請(qǐng)求沒(méi)有收到主機(jī)B的確認(rèn),于是經(jīng)過(guò)一段時(shí)間后,主機(jī)A又重新向主機(jī)B發(fā)送連接請(qǐng)求,且建立成功,順序完成數(shù)據(jù)傳輸。考慮這樣一種特殊情況,主機(jī)A第一次發(fā)送的連接請(qǐng)求并沒(méi)有丟失,而是因?yàn)榫W(wǎng)絡(luò)節(jié)點(diǎn)導(dǎo)致延遲達(dá)到主機(jī)B,主機(jī)B以為是主機(jī)A又發(fā)起的新連接,于是主機(jī)B同意連接,并向主機(jī)A發(fā)回確認(rèn),但是此時(shí)主機(jī)A根本不會(huì)理會(huì),主機(jī)B就一直在等待主機(jī)A發(fā)送數(shù)據(jù),導(dǎo)致主機(jī)B的資源浪費(fèi)。
(3)采用兩次握手不行,原因就是上面說(shuō)的實(shí)效的連接請(qǐng)求的特殊情況。