安全的關閉連線
很多人寫的伺服器網路庫有乙個難以接受的缺陷(包括我曾就職公司的一些同事),當伺服器程式主動關閉連線時,剛發往客戶端的包有時出現丟失,這時他們推薦的方式往往是傳送資料後等待幾秒再關閉連線。豪無疑問,這是一種笨拙的實現方式,他們遇到的問題根源是什麼呢?
在非iocp模式網路程式中,你只要簡單的呼叫closesocket函式就可以確保資料在作業系統釋放socket之前安全到達對方,但在iocp模式下,如果呼叫closesocket時有未決的pending io將導致socket被重置,所以有時會出現資料丟失。正統的解決方式是使用shutdown函式(指定sd_send標誌),注意這時可能有未完成的傳送pengding io,所以你應該監測是否該連線的所有是否已完成(也許你要用乙個計數器來跟蹤這些pending io),僅在所有send pending io完成後呼叫shutdown。
當你呼叫shutdown時,也許資料仍然停留在作業系統的緩衝,作業系統將在資料傳送完後發出乙個fin包來啟動關閉程序,客戶端接收完資料後,將接受到乙個0長度的包,以此判斷連線已關閉(你寫的客戶端肯定有檢測連線關閉,不是嗎?),然後呼叫closesocket,這時伺服器的getqueuedcompletionstatus將接收到乙個資料長度為0的包,這時你就可以呼叫closesocket,並釋放相關連線資源。
在絕大部分情況下上述的過程連線能完美的關閉。如果你特別注重伺服器的安全性和健壯性,可能你還需要做乙個「連線關閉佇列」,對每個已呼叫shutdown的連線放到這個佇列,然後定時的對這個佇列掃瞄,如果乙個連線5秒(你也可以自己調整)還不能關閉,那麼就強制關閉它。
明確的說WCF需要及時關閉
剛學wcf的時候沒發現這個問題,調得很愉快卻沒有發現其實 暗藏殺機 可謂危險重重,還好後來覺得是有些不妥,於是google wcf需要關閉嗎 立馬找到了幾個的鏈結,進去一看,各位大俠均紛紛表示 關是一定要關的,但是你還不能用完就關,因為關了,就不能再開啟了,還得new,可以new的成本又有一點高 好...
明確的說WCF需要及時關閉
剛學wcf的時候沒發現這個問題,調得很愉快卻沒有發現其實 暗藏殺機 可謂危險重重,還好後來覺得是有些不妥,於是google wcf需要關閉嗎 立馬找到了幾個的鏈結,進去一看,各位大俠均紛紛表示 關是一定要關的,但是你還不能用完就關,因為關了,就不能再開啟了,還得new,可以new的成本又有一點高 好...
明確的說WCF需要及時關閉
剛學wcf的時候沒發現這個問題,調得很愉快卻沒有發現其實 暗藏殺機 可謂危險重重,還好後來覺得是有些不妥,於是google wcf需要關閉嗎 立馬找到了幾個的鏈結,進去一看,各位大俠均紛紛表示 關是一定要關的,但是你還不能用完就關,因為關了,就不能再開啟了,還得new,可以new的成本又有一點高 好...