TCP 协议状态解析
我們講述的都是一些基本的tcp狀態(tài),就是使用netstat可以觀察到的狀態(tài),記錄一下,以便出現(xiàn)問(wèn)題的時(shí)候一個(gè)思路。先大概敘述一下三次握手和四次握手的機(jī)制。
1、建立連接(三次握手)
? ? (1)服務(wù)器會(huì)處于listen狀態(tài),客戶端發(fā)送一個(gè)帶SYN標(biāo)志的TCP報(bào)文到服務(wù)器。? ? (2)服務(wù)器端回應(yīng)客戶端的,這是三次握手中的第2個(gè)報(bào)文,這個(gè)報(bào)文同時(shí)帶ACK標(biāo)志和SYN標(biāo)志。
因此它表示對(duì)剛才客戶端SYN報(bào)文的回應(yīng);同時(shí)又標(biāo)志SYN給客戶端,詢問(wèn)客戶端是否準(zhǔn)備好進(jìn)行數(shù)據(jù)通訊。
? ? (3) 客戶必須再次回應(yīng)服務(wù)段一個(gè)ACK報(bào)文,這個(gè)時(shí)候兩端就處于已經(jīng)建立連接。2、連接終止(四次握手)
? ? 由于TCP連接是全雙工的,因此每個(gè)方向都必須單獨(dú)進(jìn)行關(guān)閉。這原則是當(dāng)一方完成它的數(shù)據(jù)發(fā)送任務(wù)后就能發(fā)送一個(gè)FIN來(lái)終止這個(gè)方向的連接。
?收到一個(gè) FIN只意味著這一方向上沒(méi)有數(shù)據(jù)流動(dòng),一個(gè)TCP連接在收到一個(gè)FIN后仍能發(fā)送數(shù)據(jù)。首先進(jìn)行關(guān)閉的一方將執(zhí)行主動(dòng)關(guān)閉,而另一方執(zhí)行被動(dòng)關(guān)閉。
? ? (1) 客戶端發(fā)送一個(gè)FIN,用來(lái)關(guān)閉客戶到服務(wù)器的數(shù)據(jù)傳送。
(2) 服務(wù)器收到這個(gè)FIN,它發(fā)回一個(gè)ACK,確認(rèn)序號(hào)為收到的序號(hào)加1。
? ? (3) 服務(wù)器關(guān)閉客戶端的連接,發(fā)送一個(gè)FIN給客戶端 。? ? (4) 客戶段發(fā)回ACK報(bào)文確認(rèn),并將確認(rèn)序號(hào)設(shè)置為收到序號(hào)加1。
3、狀態(tài)說(shuō)明
LISTEN: 表示服務(wù)器端的某個(gè)SOCKET處于監(jiān)聽(tīng)狀態(tài),可以接受連接。
? SYN_RCVD: 表示接受到了SYN報(bào)文,在正常情況下,服務(wù)器端收到客戶端第一個(gè)報(bào)文并且回應(yīng)客戶端之后會(huì)進(jìn)入這個(gè)狀態(tài),如果客戶端一直不回應(yīng)ACK的話,服務(wù)器的socket就會(huì)處于這個(gè)狀態(tài)(當(dāng)客戶端可以ping通服務(wù)器,可是服務(wù)器ping不通客戶端的時(shí)候會(huì)出現(xiàn)這個(gè)情況)。
SYN_SENT:與SYN_RCVD遙想呼應(yīng),這個(gè)狀態(tài)表示客戶端發(fā)送了SYN消息給服務(wù)器,但是還沒(méi)收到服務(wù)器回應(yīng)的ACK,所以的話當(dāng)服務(wù)器ping不通的時(shí)候回進(jìn)入到這個(gè)狀態(tài)。
FIN_WAIT_1:其實(shí)FIN_WAIT_1和FIN_WAIT_2狀態(tài)都是表示等待對(duì)方的FIN報(bào)文。而這兩種狀態(tài)的區(qū)別是:FIN_WAIT_1狀態(tài)實(shí)際上是當(dāng)SOCKET在ESTABLISHED狀態(tài)時(shí),它想主動(dòng)關(guān)閉連接,向?qū)Ψ桨l(fā)送了FIN報(bào)文,此時(shí)該SOCKET即進(jìn)入到FIN_WAIT_1狀態(tài)。而當(dāng)對(duì)方回應(yīng)ACK報(bào)文后,則進(jìn)入到FIN_WAIT_2狀態(tài)。當(dāng)然在實(shí)際的正常情況下,無(wú)論對(duì)方何種情況下,都應(yīng)該馬上回應(yīng)ACK報(bào)文,所以FIN_WAIT_1狀態(tài)一般是比較難見(jiàn)到的,而FIN_WAIT_2狀態(tài)還有時(shí)常常可以用netstat看到。
FIN_WAIT_2:實(shí)際上FIN_WAIT_2狀態(tài)下的SOCKET,表示半連接,也即有一方要求close連接,但另外還告訴對(duì)方,還有點(diǎn)數(shù)據(jù)需要傳送給你,稍后再關(guān)閉連接。
TIME_WAIT:表示收到了對(duì)方的FIN報(bào)文,并發(fā)送出了ACK報(bào)文,就等2MSL后即可回到CLOSED可用狀態(tài)了。如果FIN_WAIT_1狀態(tài)下,收到了對(duì)方同時(shí)帶FIN標(biāo)志和ACK標(biāo)志的報(bào)文時(shí),可以直接進(jìn)入到TIME_WAIT狀態(tài),而無(wú)須經(jīng)過(guò)FIN_WAIT_2狀態(tài)。(這個(gè)狀態(tài)只有服務(wù)器主動(dòng)關(guān)閉的時(shí)候才會(huì)出現(xiàn))
CLOSING:這種狀態(tài)比較特殊,實(shí)際情況中應(yīng)該是很少見(jiàn)。正常情況下,當(dāng)你發(fā)送FIN報(bào)文后,按理來(lái)說(shuō)是應(yīng)該先收到(或同時(shí)收到)對(duì)方的ACK報(bào)文,再收到對(duì)方的FIN報(bào)文。但是CLOSING狀態(tài)表示你發(fā)送FIN報(bào)文后,并沒(méi)有收到對(duì)方的ACK報(bào)文,反而卻也收到了對(duì)方的FIN報(bào)文。什么情況下會(huì)出現(xiàn)此種情況呢?那就是如果雙方幾乎在同時(shí)close一個(gè)SOCKET的話,那么就出現(xiàn)了雙方同時(shí)發(fā)送FIN報(bào)文的情況,也即會(huì)出現(xiàn)CLOSING狀態(tài),表示雙方都正在關(guān)閉SOCKET連接。
CLOSE_WAIT:表示在等待關(guān)閉。當(dāng)對(duì)方close一個(gè)SOCKET后發(fā)送FIN報(bào)文給自己,需要回應(yīng)一個(gè)ACK報(bào)文給對(duì)方,此時(shí)則進(jìn)入到CLOSE_WAIT狀態(tài)。接下來(lái)呢,需要考慮是否還有數(shù)據(jù)發(fā)送給對(duì)方,如果沒(méi)有,那么可以close這個(gè)SOCKET,發(fā)送FIN報(bào)文給對(duì)方,關(guān)閉連接。
特別說(shuō)明一下TIME_WAIT,這個(gè)的話只有在服務(wù)器主動(dòng)關(guān)閉,并且客戶端也給予回應(yīng)的時(shí)候會(huì)出現(xiàn),需要等待2MSL的時(shí)候才可以重新使用該socket的端口。所以的話在編程的時(shí)候我們一般都需要復(fù)用這個(gè)端口,setsocketopt的時(shí)候需要將SO_REUSEADDR置為1,那樣的話就不需要等2MSL的時(shí)候就可以立即使用該端口去綁定socket了。
2015年12月11日00:08:20
總結(jié)
以上是生活随笔為你收集整理的TCP 协议状态解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 整体C#与Sql培训内容及结构
- 下一篇: Java Set接口详细讲解 TreeS