2012-03-30 6 views
1

Ich arbeite mit einer Windows-Formularanwendung in C#. Ich benutze einen Socket-Client, der sich asynchron mit einem Server verbindet. Ich möchte, dass der Socket versucht, sich sofort wieder mit dem Server zu verbinden, wenn die Verbindung aus irgendeinem Grund unterbrochen wird. Welches ist das beste Design, um das Problem anzugehen? Soll ich einen Thread erstellen, der ständig prüft, ob die Verbindung verloren ist und versucht, sich wieder mit dem Server zu verbinden? HierDesign-Option zum automatischen Wiederverbinden von Socket-Client

ist der Code meiner XcomClient Klasse, die die Socket-Kommunikation ist der Umgang:

 public void StartConnecting() 
    { 
     socketClient.BeginConnect(this.remoteEP, new AsyncCallback(ConnectCallback), this.socketClient); 
    } 

    private void ConnectCallback(IAsyncResult ar) 
    { 
     try 
     { 
      // Retrieve the socket from the state object. 
      Socket client = (Socket)ar.AsyncState; 

      // Complete the connection. 
      client.EndConnect(ar); 

      // Signal that the connection has been made. 
      connectDone.Set(); 

      StartReceiving(); 

      NotifyClientStatusSubscribers(true); 
     } 
     catch(Exception e) 
     { 
      if (!this.socketClient.Connected) 
       StartConnecting(); 
      else 
      { 

      } 
     } 
    } 

    public void StartReceiving() 
    { 
     StateObject state = new StateObject(); 
     state.workSocket = this.socketClient; 
     socketClient.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(OnDataReceived), state); 
    } 

    private void OnDataReceived(IAsyncResult ar) 
    { 
     try 
     { 
      StateObject state = (StateObject)ar.AsyncState; 
      Socket client = state.workSocket; 

      // Read data from the remote device. 
      int iReadBytes = client.EndReceive(ar); 
      if (iReadBytes > 0) 
      { 
       byte[] bytesReceived = new byte[iReadBytes]; 
       Buffer.BlockCopy(state.buffer, 0, bytesReceived, 0, iReadBytes); 
       this.responseList.Enqueue(bytesReceived); 
       StartReceiving(); 
       receiveDone.Set(); 
      } 
      else 
      { 
       NotifyClientStatusSubscribers(false); 
      } 
     } 
     catch (SocketException e) 
     { 
      NotifyClientStatusSubscribers(false); 
     } 
    } 

Heute versuche ich, eine Trennung zu fangen, indem die Anzahl der empfangenen Bytes oder fängt eine Socket Ausnahme überprüfen.

+0

Das hängt davon ab, welche Klassen Sie verwenden. Sie poste besser Ihren Code hier oder geben Sie uns mehr Info. –

Antwort

2

Wenn Ihre Anwendung nur Daten über einen Socket empfängt, werden Sie in den meisten Fällen keine unterbrochene Verbindung erkennen. Wenn Sie längere Zeit keine Daten erhalten, wissen Sie nicht, ob die Verbindung unterbrochen ist oder das andere Ende einfach keine Daten gesendet hat. Sie werden natürlich (wie EOF an der Steckdose) Verbindungen erkennen, die auf die andere Art und Weise geschlossen sind.

Um eine unterbrochene Verbindung zu erkennen, benötigen Sie ein Keepalive. Sie müssen entweder:

  • das andere Ende garantieren, dass es Daten auf einem festgelegten Zeitplan senden wird, und Sie Zeit und die Verbindung schließen, wenn Sie es nicht bekommen, oder,
  • eine Sonde schicken zum anderen Ende hin und wieder. In diesem Fall wird das Betriebssystem darauf achten, eine unterbrochene Verbindung zu bemerken, und Sie erhalten einen Fehler beim Lesen des Sockets, wenn dieser unterbrochen wird, entweder sofort (Verbindung durch Peer zurückgesetzt) ​​oder schließlich (Zeitüberschreitung der Verbindung).

In jedem Fall benötigen Sie einen Timer. Ob Sie den Timer als Event in einer Event-Schleife implementieren oder ob ein Thread, der schläft, liegt bei Ihnen, und die beste Lösung hängt wahrscheinlich davon ab, wie der Rest Ihrer Anwendung strukturiert ist. Wenn Sie einen Haupt-Thread haben, der eine Event-Schleife ausführt, ist es wahrscheinlich am besten, sich daran anzumelden.

Sie können auch die TCP-Keepalives-Option für den Socket aktivieren, aber ein Keepalive auf Anwendungsebene wird im Allgemeinen als robuster angesehen.

Verwandte Themen