Как я могу узнать, было ли разорвано соединение в моем клиенте на основе сокетов? - PullRequest
6 голосов
/ 25 марта 2009

Если соединение моего клиента оборвано на другом end( kill -9 server). Клиенту требуется несколько минут, чтобы определить, что что-то не так. Socket.Connected возвращает true, даже если соединение на самом деле разорвано.

Какой самый быстрый способ определить, что соединение не существует, когда другой конец разорвет связь?

Код клиента:

try{
      Socket socket= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
     /*Assume there is a connection on the other end*/
      while (socket.Connected)
      {

          /*Do some processing*/
      }
 }catch (SocketException se){
       Console.WriteLine(ex.Message);
 } catch (Exception ex){
       Console.WriteLine(ex.Message);
 }
 finally
 {
   Console.WriteLine("something bad happen");
 }

Ответы [ 6 ]

3 голосов
/ 25 марта 2009

Это, кажется, работает для меня ... Кто-нибудь видит какие-либо проблемы?

public bool IsConnected
{
         get {return !(Socket.Poll(1, SelectMode.SelectRead) 
                                  && m_socket.Available ==0)}
}

Можно также добавить в метод расширения.

public static class SocketExtensions
{
  public static bool IsConnected(this Socket @this)
  {
    return !(@this.Poll(1, SelectMode.SelectRead) && @this.Available == 0);
  }
}

Теперь вы можете легко использовать его в своем коде, работающем с сокетами.

var mySocket = new Socket();
while(mySocket.IsConncted())
{
  // Do Stuff
}
1 голос
/ 25 марта 2009

Попробуйте проверить свойство Available, оно должно выдать SocketException, когда соединение было закрыто.

Источник

Редактировать , вот как бы вы его использовали:

while(socket.Connected)
{
  try
  {
    while (socket.Available == 0)
      System.Threading.Thread.Sleep(100); // Zzzz
  }
  catch (SocketException)
  {
    // connection closed
    // do something
  }

  /* Do some processing */
}

Вы также можете попробовать использовать метод Poll.

Из Источник :

Кроме того, вы также можете использовать метод опроса Poll () с SelectRead SelectMode параметр. это метод вернет истинное значение, если данные доступны или если соединение был закрыт удаленным хостом. Затем вам нужно будет дифференцировать между какими из этих ситуаций произошло (читая сокет буфера, и посмотреть, если он возвращает нулевое значение).

1 голос
/ 25 марта 2009

Создает другой поток, который постоянно проверяет связь с сервером - действительно лучшее, что вы можете сделать, поскольку сокет не является активным соединением.

0 голосов
/ 26 марта 2009

Я отсылаю вас к моему ответу к вашей версии C ++ этого вопроса ...

0 голосов
/ 25 марта 2009

Может быть, SendTimeout и / или ReadTimeout свойства Socket могут помочь?

0 голосов
/ 25 марта 2009

Вы пытались установить более короткое время ожидания соединения?

...