2011-07-10 73 views
1

客戶端斷開連接在服務器端我有這樣的代碼,其在新的線程中運行.NET插座的問題:從服務器

static void ListenForConsultant() 
    { 
     while (true) 
     { 
      var serverSocket = new TcpListener(IPAddress.Any, 2111); 
      serverSocket.Start(); 
      var clientSocket = serverSocket.AcceptTcpClient(); 
      consultantConnected = true; 
      Console.WriteLine(" >> Consultant Connected"); 
      byte[] bytesFrom = new byte[10025]; 
      while (true) 
      { 
       if (!clientSocket.Connected) 
       { 
        break; 
       } 
       NetworkStream networkStream = clientSocket.GetStream(); 
       bytesFrom = new byte[10025]; 
       networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize); 
       var dataFromConsultant = System.Text.Encoding.ASCII.GetString(bytesFrom); 
       if (dataFromConsultant.IndexOf("~") != -1 && dataFromConsultant.IndexOf("^") != -1 && dataFromConsultant.IndexOf("^") > dataFromConsultant.IndexOf("~")) 
       { 
        var lengthOfMessage = dataFromConsultant.IndexOf("^") - dataFromConsultant.IndexOf("~") - 1; 
        dataFromConsultant = dataFromConsultant.Substring(dataFromConsultant.IndexOf("~") + 1, lengthOfMessage); 
        Console.WriteLine(" >> From consultant:" + dataFromConsultant); 
       } 

      } 

      consultantConnected = false; 
      Console.WriteLine(" >> Consultant Disconnected"); 

      serverSocket.Stop(); 
     } 
    } 

我連接使用膩子端口2111的所有工作正常,但是當我關閉膩子插座沒有按關閉,但我有條件

if (!clientSocket.Connected) 
{ 
     break; 
} 

調試顯示,即使從服務器斷開連接後,clientSocket.Connected爲true。

爲什麼會發生這種情況?

回答

2

tcpClient.Connected屬性值不可靠,它的值取決於上次的通信;所以如果最後的溝通是成功的,那麼它的價值是真的,否則它是錯誤的。有關該檢查的更多信息this

使用此IsConnected屬性檢查TcpClient的連接:

public static bool IsConnected 
{ 
    get 
    { 
     try 
     { 
      //return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected; 

      if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected) 
      { 

       /* As the documentation: 
        * When passing SelectMode.SelectRead as a parameter to the Poll method it will return 
        * -either- true if Socket.Listen(Int32) has been called and a connection is pending; 
        * -or- true if data is available for reading; 
        * -or- true if the connection has been closed, reset, or terminated; 
        * otherwise, returns false 
        */ 

       // Detect if client disconnected 
       if (_tcpClient.Client.Poll(0, SelectMode.SelectRead)) 
       { 
        byte[] buff = new byte[1]; 
        if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0) 
        { 
         // Client disconnected 
         return false; 
        } 
        else 
        { 
         return true; 
        } 
       } 

       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
     catch 
     { 
      return false; 
     } 
    } 
} 

編輯:注意檢查IsConnected不會阻止其斷開檢查後。也就是說,在「IsConnected檢查評估並返回true」之後,可能會發生套接字在連接之後斷開連接,因此您應該將所有通信封裝在try/catchtry/catch/finally塊中,以期隨時斷開套接字的連接。

+0

我應該用什麼來代替這個屬性來確定客戶端的狀態? – takayoshi

+0

更新了答案:代碼[來自我以前的答案](http://stackoverflow.com/questions/6452992/tcpclient-disconnect-during-async-read/6455369#6455369)。 –