time_wait
timewait先發起close的一端的第二階段:
a fin b,b ack a,b fin a 此時a收到b的fin之后,a處於time_wait,a無法確定自己接下來的ack of fin是否被b收到,所以time_wait還是會持續一段時間。接着可能發生兩件事情:
- 收到b的fin重傳(因為b沒有收到ack)
- 相當長一段時間——2MSL,都沒有收到b的fin重傳
第一種,那么a可以確定第一次的ack沒有及時到達b,繼續發送ack,直到發生第二種。此時a可以關閉連接,因為在第一個MSL內,a收到的最后一次fin包發送之前的數據包都已經從網絡消失,因為這些數據包到此時已經超過了MSL;又繼續等待第二個MSL,確保a發送的ack消失之前重發的fin都沒有到達a,而且在ack消失的同時對方重發的fin也已經消失——那么說明網絡狀態要么足夠差,重發這么多fin都沒有被a收到,要么a的ack已經被b接收。
理解為什么是2MSL的原因:假設網絡狀態極好,fin的ack立即被對方b接收到,對方立即close,那么此時a應該等待1MSL,因為只有等待這么久才能確保對方close之前的包都已經在網絡中超時消失。但是如果ack有延遲T才到達b,那么a應該等待T+MSL;ack實際上最大的延遲是MSL,所以TIME_WAI應該等待2MSL再變成close。
保持2MSL並不是為了解決所有問題,只是為了防止一個問題,那就是防止對方真的close后,還有包在網絡中傳遞,並不是為了確保對方連重傳的fin包都消失,實際上應該假設對方重傳的fin包一定會被a收到。
再看b的close,應用層在socketclose之后,可能已經進程退出了,只不過內核還有socket的狀態在維護,當然進程可能沒有退出。