簡體   English   中英

C#SocketAsyncEventArgs和網絡故障

[英]C# SocketAsyncEventArgs and network glitches

我已經以規范的方式使用SAEA實現了異步套接字:

  1. 擁有准備運行的SAEA池,保留引用,以便GC不必移動內存
  2. 操作完成后,請更換SAEA。

我發現了與網絡中斷有關的問題。 具體來說, 當發生中斷時 ,sendAsync完成事件不會觸發 ,因此不會重新填充我的池。 最終最終導致程序崩潰,因為無論池的大小如何,它都將耗盡SAEA。

您如何避免這種情況? 您不能簡單地保留對舊SAEA的引用,因為這將為您提供一個例外,表明它已經在等待操作。

我正在尋找一種方法來優雅地替換SAEA。 數據不被傳輸不是問題。 一種可行的方法是一旦有一定數量的對象正在等待,就在套接字上運行關機。 有人有經驗嗎?

實際上,在基本無限的網絡延遲情況下(就像在切斷電纜的情況下),沒有完成沒有發布。

解決此類問題的唯一方法是實施某些版本的心跳方案。 套接字上存在SO_KEEPALIVE選項,但是默認行為通常不是您想要的。 從MSDN:

對於TCP,默認的保持活動超時時間為2小時,保持活動時間間隔為1秒。

我建議您實施自己的心跳方案,如果在合理的時間內未收到響應心跳,則認為連接“死”。 例如,您可以:

  1. 定期發送“心跳”(或沒有其他消息發送時)
  2. 記下接收到心跳(或任何)消息的時間,並設置超時,以便如果觸發了超時,則表示您接收數據的時間太長,因此應關閉連接並重新啟動

提出的解決方案確實有效。 只需在每次發送之前檢查是否超出了某個限制,然后關閉並關閉套接字即可。 這樣可以防止對象泄漏,並在以后允許正常重新連接。

我通過拔下電纜並反復重新連接進行了測試。 在舊情況下,池將為空。 現在,它可以在網絡中斷后幸存下來。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM