1、建立連接協(xié)議(三次握手)
?。?)客戶(hù)端發(fā)送一個(gè)帶SYN標志的TCP報文到服務(wù)器。這是三次握手過(guò)程中的報文1.
?。?) 服務(wù)器端回應客戶(hù)端的,這是三次握手中的第2個(gè)報文,這個(gè)報文同時(shí)帶ACK標志和SYN標志。因此它表示對剛才客戶(hù)端SYN報文的回應;同時(shí)又標志SYN給客戶(hù)端,詢(xún)問(wèn)客戶(hù)端是否準備好進(jìn)行數據通訊。
?。?) 客戶(hù)必須再次回應服務(wù)段一個(gè)ACK報文,這是報文段3.
2、連接終止協(xié)議(四次握手)
由于TCP連接是全雙工的,因此每個(gè)方向都必須單獨進(jìn)行關(guān)閉。這原則是當一方完成它的數據發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向的連接。收到一個(gè)FIN只意味著(zhù)這一方向上沒(méi)有數據流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數據。首先進(jìn)行關(guān)閉的一方將執行主動(dòng)關(guān)閉,而另一方執行被動(dòng)關(guān)閉。
?。?) TCP客戶(hù)端發(fā)送一個(gè)FIN,用來(lái)關(guān)閉客戶(hù)到服務(wù)器的數據傳送(報文段4)。
?。?) 服務(wù)器收到這個(gè)FIN,它發(fā)回一個(gè)ACK,確認序號為收到的序號加1(報文段5)。和SYN一樣,一個(gè)FIN將占用一個(gè)序號。
?。?) 服務(wù)器關(guān)閉客戶(hù)端的連接,發(fā)送一個(gè)FIN給客戶(hù)端(報文段6)。
?。?) 客戶(hù)段發(fā)回ACK報文確認,并將確認序號設置為收到序號加1(報文段7)。
CLOSED: 這個(gè)沒(méi)什么好說(shuō)的了,表示初始狀態(tài)。
LISTEN: 這個(gè)也是非常容易理解的一個(gè)狀態(tài),表示服務(wù)器端的某個(gè)SOCKET處于監聽(tīng)狀態(tài),可以接受連接了。
SYN_RCVD:這個(gè)狀態(tài)表示接受到了SYN報文,在正常情況下,這個(gè)狀態(tài)是服務(wù)器端的SOCKET在建立TCP連接時(shí)的三次握手會(huì )話(huà)過(guò)程中的一個(gè)中間狀態(tài),很短暫,基本上用netstat你是很難看到這種狀態(tài)的,除非你特意寫(xiě)了一個(gè)客戶(hù)端測試程序,故意將三次TCP握手過(guò)程中最后一個(gè)ACK報文不予發(fā)送。因此這種狀態(tài)時(shí),當收到客戶(hù)端的ACK報文后,它會(huì )進(jìn)入到ESTABLISHED狀態(tài)。
SYN_SENT:這個(gè)狀態(tài)與SYN_RCVD遙想呼應,當客戶(hù)端SOCKET執行CONNECT連接時(shí),它首先發(fā)送SYN報文,因此也隨即它會(huì )進(jìn)入到了SYN_SENT狀態(tài),并等待服務(wù)端的發(fā)送三次握手中的第2個(gè)報文。SYN_SENT狀態(tài)表示客戶(hù)端已發(fā)送SYN報文。
ESTABLISHED:這個(gè)容易理解了,表示連接已經(jīng)建立了。
FIN_WAIT_1:這個(gè)狀態(tài)要好好解釋一下,其實(shí)FIN_WAIT_1和FIN_WAIT_2狀態(tài)的真正含義都是表示等待對方的FIN報文。而這兩種狀態(tài)的區別是:FIN_WAIT_1狀態(tài)實(shí)際上是當SOCKET在ESTABLISHED狀態(tài)時(shí),它想主動(dòng)關(guān)閉連接,向對方發(fā)送了FIN報文,此時(shí)該SOCKET即進(jìn)入到FIN_WAIT_1狀態(tài)。而當對方回應ACK報文后,則進(jìn)入到FIN_WAIT_2狀態(tài),當然在實(shí)際的正常情況下,無(wú)論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1狀態(tài)一般是比較難見(jiàn)到的,而FIN_WAIT_2狀態(tài)還有時(shí)常??梢杂胣etstat看到。
FIN_WAIT_2:上面已經(jīng)詳細解釋了這種狀態(tài),實(shí)際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對方,我暫時(shí)還有點(diǎn)數據需要傳送給你,稍后再關(guān)閉連接。
TIME_WAIT:表示收到了對方的FIN報文,并發(fā)送出了ACK報文,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FIN_WAIT_1狀態(tài)下,收到了對方同時(shí)帶FIN標志和ACK標志的報文時(shí),可以直接進(jìn)入到TIME_WAIT狀態(tài),而無(wú)須經(jīng)過(guò)FIN_WAIT_2狀態(tài)。
CLOSING:這種狀態(tài)比較特殊,實(shí)際情況中應該是很少見(jiàn),屬于一種比較罕見(jiàn)的例外狀態(tài)。正常情況下,當你發(fā)送FIN報文后,按理來(lái)說(shuō)是應該先收到(或同時(shí)收到)對方的ACK報文,再收到對方的FIN報文。但是CLOSING狀態(tài)表示你發(fā)送FIN報文后,并沒(méi)有收到對方的ACK報文,反而卻也收到了對方的FIN報文。什么情況下會(huì )出現此種情況呢?其實(shí)細想一下,也不難得出結論:那就是如果雙方幾乎在同時(shí)close一個(gè)SOCKET的話(huà),那么就出現了雙方同時(shí)發(fā)送FIN報文的情況,也即會(huì )出現CLOSING狀態(tài),表示雙方都正在關(guān)閉SOCKET連接。
CLOSE_WAIT:這種狀態(tài)的含義其實(shí)是表示在等待關(guān)閉。怎么理解呢?當對方close一個(gè)SOCKET后發(fā)送FIN報文給自己,你系統毫無(wú)疑問(wèn)地會(huì )回應一個(gè)ACK報文給對方,此時(shí)則進(jìn)入到CLOSE_WAIT狀態(tài)。接下來(lái)呢,實(shí)際上你真正需要考慮的事情是察看你是否還有數據發(fā)送給對方,如果沒(méi)有的話(huà),那么你也就可以close這個(gè)SOCKET,發(fā)送FIN報文給對方,也即關(guān)閉連接。所以你在CLOSE_WAIT狀態(tài)下,需要完成的事情是等待你去關(guān)閉連接。
LAST_ACK: 這個(gè)狀態(tài)還是比較容易好理解的,它是被動(dòng)關(guān)閉一方在發(fā)送FIN報文后,最后等待對方的ACK報文。當收到ACK報文后,也即可以進(jìn)入到CLOSED可用狀態(tài)了。
最后有2個(gè)問(wèn)題的回答,我自己分析后的結論(不一定保證100%正確)
1、 為什么建立連接協(xié)議是三次握手,而關(guān)閉連接卻是四次握手呢?
這是因為服務(wù)端的LISTEN狀態(tài)下的SOCKET當收到SYN報文的建連請求后,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個(gè)報文里來(lái)發(fā)送。但關(guān)閉連接時(shí),當收到對方的FIN報文通知時(shí),它僅僅表示對方?jīng)]有數據發(fā)送給你了;但未必你所有的數據都全部發(fā)送給對方了,所以你可以未必會(huì )馬上會(huì )關(guān)閉SOCKET,也即你可能還需要發(fā)送一些數據給對方之后,再發(fā)送FIN報文給對方來(lái)表示你同意現在可以關(guān)閉連接了,所以它這里的ACK報文和FIN報文多數情況下都是分開(kāi)發(fā)送的。
2、 為什么TIME_WAIT狀態(tài)還需要等2MSL后才能返回到CLOSED狀態(tài)?
這是因為:雖然雙方都同意關(guān)閉連接了,而且握手的4個(gè)報文也都協(xié)調和發(fā)送完畢,按理可以直接回到CLOSED狀態(tài)(就好比從SYN_SEND狀態(tài)到ESTABLISH狀態(tài)那樣);但是因為我們必須要假想網(wǎng)絡(luò )是不可靠的,你無(wú)法保證你最后發(fā)送的ACK報文會(huì )一定被對方收到,因此對方處于LAST_ACK狀態(tài)下的SOCKET可能會(huì )因為超時(shí)未收到ACK報文,而重發(fā)FIN報文,所以這個(gè)TIME_WAIT狀態(tài)的作用就是用來(lái)重發(fā)可能丟失的ACK報文
聯(lián)系客服