TCP狀態(tài)轉(zhuǎn)換示意圖如下
針對上面的示意圖,主要對以下幾點進行解析:
有哪些進程狀態(tài)是可以捕捉到的?
-
- LISTEN、ESTABLISHED、等,其他狀態(tài)時間很短暫,捕捉不到
- netstat命令可以捕捉狀態(tài)。
2MSL是什么?
-
- 2MSL是等待時長,主動關(guān)閉連接的一方將會處于TIME_WAIT狀態(tài)
- 1MSL大概是30S,處于TIME_WAIT狀態(tài)的進程(主動斷開連接的進程)不會立即終止,而是會等待2MSL的時間;而被動斷開連接的一方,在LAST_ACK狀態(tài),一旦收到對方的ACK就會立即終止進程。
為什么主動斷開的一方要等2MSL而被動斷開的一方不需要等呢?
因為有可能會出現(xiàn)這種情況,主動斷開的一方(比如是client)屬于TIME_WAIT時,向被斷開的一方(比如說server)發(fā)送ACK,有可能對方?jīng)]有收到,這時侯server會再發(fā)一次FIN,也就需要client再回復(fù)一次ACK(如果client沒有等待就終止了,那么server發(fā)送的FIN就發(fā)送不到了,四次揮手就失敗了),所以主動斷開連接的一方要等待,來保證正常斷開連接,而被斷開的一方收到ACK就可以終止進程了,此時連接正常斷開。
什么是半關(guān)閉?
如何理解半關(guān)閉
-
- A給B發(fā)送FIN(A調(diào)用了close函數(shù)), 但是B沒有給A發(fā)送FIN(B沒有調(diào)用close)
- A斷開了與B的連接, B沒有斷開與A的連接
特點:
-
- ?A不能給B發(fā)送數(shù)據(jù), A可以收B發(fā)送的數(shù)據(jù)
- B可以給A發(fā)送數(shù)據(jù)
函數(shù): int shutdown(int sockfd, int how);
sockfd: 要半關(guān)閉的一方對應(yīng)的文件描述符
通信的文件描述符
how:(可以只關(guān)讀、只關(guān)寫,或讀寫都關(guān))
-
- ?SHUT_RD ? ? - ? ? ? ? ? 0 - 讀
- SHUT_WR ? ? ? ?- ? ? ? ? ? 1 - 寫
- SHUT_RDWR ? - ? ? ? ? ? 2 - 讀寫
使用close()函數(shù)能否實現(xiàn)半關(guān)閉?
不能。使用dup2函數(shù)可以復(fù)制一個文件描述符fd指向和sfd一樣的內(nèi)容,如果使用close(fd)關(guān)閉了對內(nèi)核緩沖區(qū)的讀寫,但是還存在一個文件描述符sfd可以讀寫內(nèi)核緩沖區(qū),也就是說通信依然可以進行,這樣并不能實現(xiàn)真正的半關(guān)閉。使用shutdown函數(shù)可以實現(xiàn)半關(guān)閉,是因為shutdown(fd, SHUT_RD)雖然在函數(shù)中只對fd關(guān)閉了讀,但是它實際上是將緩沖區(qū)的讀給關(guān)閉了,所有文件描述符(不管有多少個),都不能再讀緩沖區(qū)了。
在使用套接字通信時,可以使用netstat命令捕捉進程狀態(tài)或使用netstat查看網(wǎng)絡(luò)相關(guān)狀態(tài)信息,netstat的常用參數(shù)如下:
-a (all)顯示所有選項,默認不顯示LISTEN相關(guān)進程,不加-a就不顯示LISTEN進程。
-p 顯示建立相關(guān)鏈接的程序名。
-n 拒絕顯示別名,能顯示數(shù)字的全部轉(zhuǎn)化成數(shù)字。
-t (tcp)僅顯示tcp相關(guān)選項。
-u (udp)僅顯示udp相關(guān)選項。
-l 僅列出有在 Listen (監(jiān)聽) 的服務(wù)狀態(tài)。