2016-05-27 52 views
0

我寫了一個tcp服務器,每次接受客戶端連接時,由AcceptEndAccept返回的套接字實例被稱爲處理程序和許多其他信息收集在名爲TcpClientConnection的對象中,我需要確定是否連接是否連接或在某些特定間隔時間,Socket.Connected屬性是不可靠的,根據文檔我應該使用Poll方法與SelectRead選項來執行此操作。 與測試場景我拔掉客戶端電纜,並等待破損的報警建立在handler.Poll(1, SelectMode.SelectRead)上,它應該返回true,但從未發生過。確定TCP服務器中的斷開連接

+1

你能否提供一些代碼? – Henningsson

回答

1

根據Socket.Poll的文檔:

這種方法不能檢測某些種連接問題,例如一個破碎網絡電纜,或遠程主機被非正常關閉。您必須嘗試發送或接收數據以檢測這些類型的錯誤。

換句話說 - 輪詢對於檢查是否有數據到達並可用於本地OS網絡堆棧很有用。 如果你需要檢測連接問題,你需要調用阻塞讀取(例如Socket.Receive

你也可以建立一個簡單的初始化miniprotocol來交換一些同意的'hello'來回消息。 下面是一個簡單的例子,你可以怎麼做:

private bool VerifyConnection(Socket socket) 
    { 
     byte[] b = new byte[1]; 
     try 
     { 
      if (socket.Receive(b, 0, 1, SocketFlags.None) == 0) 
       throw new SocketException(System.Convert.ToInt32(SocketError.ConnectionReset)); 
      socket.NoDelay = true; 
      socket.Send(new byte[1] { SocketHelper.HelloByte }); 
      socket.NoDelay = false; 
     } 
     catch (Exception e) 
     { 
      this._logger.LogException(LogLevel.Fatal, e, "Attempt to connect (from: [{0}]), but encountered error during reading initialization message", socket.RemoteEndPoint); 
      socket.TryCloseSocket(this._logger); 
      return false; 
     } 


     if (b[0] != SocketHelper.HelloByte) 
     { 
      this._logger.Log(LogLevel.Fatal, 
       "Attempt to connect (from: [{0}]), but incorrect initialization byte sent: [{1}], Ignoring the attempt", 
       socket.RemoteEndPoint, b[0]); 
      socket.TryCloseSocket(this._logger); 
      return false; 
     } 

     return true; 
    }