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