(C# TCP異步)客戶端異常斷開,服務器利用KeepAlive監測


最近在做的項目是用C#作服務端,客戶端每隔10秒發起一次連接,出現的問題是:由於同學在做的客戶端側有一些bug暫未解決,經常會出現客戶端崩掉,但服務端卻沒有監測到socket異常斷開。

查了資料后發現有兩種方式可以解決:

1、用心跳包方式(服務端每隔幾秒向客戶端發起請求,如果沒有收到客戶端回應,則判定為客戶端下線)

2、用socket的KeepAlive機制(個人感覺和心跳包有點類似)

 

我先用了心跳包的方式測試,發現雖然確實可以將對應的socket關閉,但是延遲很大(在建立socket連接后,把客戶端斷網5s-20s,服務器才會斷開其socket連接),所以選擇使用KeepAlive機制。

 

Socket server;

//server綁定端口及監聽就不貼出來了

Socket client = server.Accept();

client.IOControl(IOControlCode.KeepAliveValues, KeepAlive(1, 3000, 500), null);//設置Keep-Alive參數
  
private byte[] KeepAlive(int onOff, int keepAliveTime, int keepAliveInterval)
{
        uint dummy = 0;
        byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3];
        BitConverter.GetBytes((uint)onOff).CopyTo(inOptionValues, 0);
        BitConverter.GetBytes((uint)keepAliveTime).CopyTo(inOptionValues, Marshal.SizeOf(dummy));//keep-alive間隔(單位ms)
        BitConverter.GetBytes((uint)keepAliveInterval).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2);// 嘗試間隔(單位ms)
        return inOptionValues;
}

 

  

設置完以后,還需要在Receive的異步回調函數的catch里執行客戶端socket的close方法(try里執行EndReceive或者下一次的BeginReceive)。

不過使用TcpClient的話好像無需在Receive的異步回調函數里手動執行close(暫未測試,下次測試后補上)。

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM