應用層的場景

1 數據中斷

socket的特點是隨時可能關閉,即發送和接受的數據隨時可能中斷。

應用層必須能處理socket數據中斷的情況。

2 無感知關閉

socket的另一邊有可能已關閉,並且我們無法感知。

應用層必須有一個心跳機制,當超過一定時間未收到心跳,則關閉socket。

SOCKET層的場景

調用close注意事項:

(1)調用close是無阻塞返回的。

(2)調用close之後,並沒有馬上釋放socket資源,可能要等待比較長的時間。因此最好設置l_linger參數,強制一定時間內回收socket。

windows的關閉行為如下:

默認是第一種情況,graceful close,意思著要把數據發完再關閉。這也就意味著萬一斷網,數據未發完,socket就無法釋放。當然按道理也不會永遠都不釋放。

關閉的時候還會遇到其他的問題,導致釋放socket時間不可控:比如主動關閉,有可能FIN發出去了收不到ACK,也可能是收不到FIN,也可能是ACK發出去了還要等2MSL。對於被動關閉,也可能會遇到ACK發不出去,FIN不出去,ACK收不到的情況,時間也不可控。

關閉時有未完成數據:

如果關閉的時候,客戶端或者伺服器還有數據要發送或者接受的話,可以忽略掉數據,直接close。應用層使用情況1的處理方式。

關閉時網路斷了的處理流程:

正常情況下,客戶端主動關閉,伺服器被動關閉。

客戶端(主動關閉)直接close。

伺服器如果未收到FIN網路就斷了,伺服器其實是沒有感知的,那麼相當於應用層場景2,伺服器等心跳超時之後,調close(主動關閉)。

伺服器如果收到FIN之後(被動關閉),網路就斷了,那麼伺服器close即可。

調用close之後,系統底層可能無法及時釋放socket,所以無論是客戶端還是伺服器,close最好都設置一下l_linger參數,強制一定時間內釋放socket。

參考

closesocket Function?

msdn.microsoft.com


推薦閱讀:

相關文章