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