none
TCP Verbindung hört auf zu empfangen RRS feed

  • Allgemeine Diskussion

  • Hallo zusammen,

    ich habe ein kleines Problem mit einer TCP IP Verbindung.

    Die Verbindung wird zwischen zwei Programmen ("Anwendung 1" & "Anwendung 2") auf demselben Rechner aufgebaut (d.h. es ist kein Kabel oder Switch dazwischen).

    Eine zeitlang funktioniert alles gut. Dann stellt die "Anwendung 2" das empfangen ein. Das Senden funktioniert nach wie vor.

    Die Verbindung wird in beiden Anwendungen weiterhin als "Verbunden" angezeigt und es werden keine Exceptions generiert.

    "Anwendung 1" sendet weiter Daten ohne Fehlermeldung an "Anwendung 2". Diese kommen dort aber nicht an.

    Da "Anwendung 1" ein zugekauftes Produkt ist, welches weltweit 1000fach eingesetzt wird, möchte ich ein Fehler hier ausschließen.

    "Anwendung 2" wird von meiner Firma programmiert, ist ein Dienst und wird für den jeweiligen Kunden angepasst. Die problematische Schnittstelle läuft allerdings bereits in in vielen Projekten jahrelang ohne Probleme.

    Das ganze läuft auf einer "Windows Server 2008 R2"-VM. Die "Anwendung 2" dabei aber im 32-Bit Betrieb, da wir in dieser Anlage ein 32-Bit COM Modul einsetzen müssen. Verwendet wird das .Net Framework 4.0.

    Ich gehe zurzeit davon aus, dass sich in "Anwendung 2" ein Fehler eingeschlichen hat. Dieses kann aber eigentlich nur ein lock() Problem oder eine Endlosschleife sein, da es keine Fehlermeldung / keine unbehandelte Ausnahme gibt.

    Nun zu meiner eigentlichen Frage (nachdem ich bereits mehrere Tage nach dem Fehler gesucht habe): Ist irgendeinem von Euch / Ihnen ein Bug in Windows / dem .Net Framework bekannt, der dieses Verhalten auslösen kann? (Dann könnte ich nämlich lage suchen)

    Vielen Dank für Eure / Ihre Hilfe.

    Mit freundlichen Grüßen / Best Regards

    Thomas Voß


    Mit freundlichen Grüßen / Best Regards Thomas


    Dienstag, 10. April 2012 15:26

Alle Antworten

  • Hallo Thomas

    TCP Sockets sind derart elementar für .NET, da sind Fehler extrem unwahrscheinlich, aber prüfe bloss zur Vollständigkeit .NET Update 4.0.3:
    http://blogs.msdn.com/b/dotnet/archive/2012/03/05/update-4-0-3-for-the-microsoft-net-framework-4.aspx
    http://go.microsoft.com/fwlink/?LinkID=226775

    Generell:
    Die meisten Programmierfehler finden sich in Code rund um Receive:
    http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receive.aspx
     (bzw andere, intern darauf aufbauende Methoden!)

    der ganz typische Fall hier, dass der Rückgabewert (Anzahl Bytes empfangen) nicht oder falsch (spekulativ) ausgewertet wird.
    Streams (wie TCP) kennen keine 'Pakete', sondern im Gegenteil sogar willkürliche Fragmentierung (auch ohne LAN-Kabel).

    Dienstag, 10. April 2012 15:51
  • Hallo,

    vielen Dank erstmal für die schnelle Antwort. Ich werde den Link / das Update mal prüfen.

    Zur 2ten Anmerkung:

    "Die meisten Programmierfehler finden sich in Code rund um Receive:"

    Wir haben umgenau solche Fehler zu vermeiden unsere "Basis"-Schnittstelle abstrahiert. Diese kümmert sich nur um die eigentlichen Funktionen wie Verbindungsaufbau zu einem EndPoint, Senden & Empfangen sowie das protokollieren der gesendeten & empfangenen Daten. Alle Telegrammdefinitionen / Auswertungen werden außerhalb dieser Basisschnittstelle in eigenen Klassen definiert / ausgewertet.

    D.h. das eigentliche senden und empfangen sollte stimmen. Ich werde mir das aber trotzdem nochmal durchlesen.

    Danke.


    Mit freundlichen Grüßen / Best Regards Thomas

    Dienstag, 10. April 2012 16:17
  • Am 10.04.2012 17:26, schrieb Thomas_21224:
    > Eine zeitlang funktioniert alles gut. Dann stellt die "Anwendung 2" das
    > empfangen ein. Das Senden funktioniert nach wie vor.
     
    Grundsatzfrage: benutzt du synchrones oder asynchrones Lesen? Letzteres
    arbeitet mit BeginRead und einer Callback-Funktion. Und ist auf jeden
    Fall zu bevorzugen. Hier mal aus dem Zusammenhang gerissen eine Callback
    Funktion, die bei mir bislang zuverlässig funktioniert hat:
     private void ReadCallback(IAsyncResult ar)
            {
                int numRead = 0;
                try
                {
                    if (Remote.Connected == true)
                        numRead = Remote.GetStream().EndRead(ar);
                }
                catch (IOException ex)
                {
                    Exception e2 = ex.GetBaseException();
                    if (Marshal.GetHRForException(e2) ==
    unchecked((Int32)0x80004005))
                        // Connection closed by remote host
                        Invoke(new Action(DoDisconnect));
                    else
                        // Other exception occured
                        MessageBox.Show(ex.Message);
                }
                 if (numRead > 0)
                {
                    strResponse = Encoding.ASCII.GetString(recvBuf, 0,
    numRead);
                    richConversation.Invoke(new Action(UpdateResponse));
                    // Start reading from the network again.
                    Remote.GetStream().BeginRead(recvBuf, 0,
    recvBuf.Length, ReadCallback, recvBuf);
                }
            } // End ReadCallback
     
    Mittwoch, 11. April 2012 08:44
  • Hallo,

    wir benutzen ein Async Callback. s. Unten die Methode. Wir haben Testausgaben in eine Datei eingebaut. Das Letzte was passiert ist die Ausgabe vor dem Endreceive. An allen stellen wo "//Hier kommt die Funktion nicht mehr hin" steht, sind ebenfalls Testausgaben eingebaut, die nicht mehr ausgegeben werden. this.client ist vom Type Socket.

            //Callback Funktion
    	private void ReadCallback(IAsyncResult asyncResult)
            {
                int nBytesReceived;
                try
                {
    		//EndReceive wird gestartet
                    nBytesReceived = this.client.EndReceive(asyncResult);
                    if (nBytesReceived < 1)
                    {
    		    //Hier kommt die Funktion nicht mehr hin
                        this.DisConnect();
                        this.ByteBuffer = new byte[InputBufferSize];
                        if (this.ConnectionClosed != null)
                        {
                            this.ConnectionClosed(this, new ConnectionClosedEventArgs());
                        }
    
                        return;
                    }
    
                    byte[] tmp = new byte[nBytesReceived];
                    Array.Copy(this.ByteBuffer, tmp, nBytesReceived);
                    if (this.ConnectionDataReceived != null)
                    {
    		    //Hier kommt die Funktion nicht mehr hin
                        this.ConnectionDataReceived(this, new ConnectionDataReceivedEventArgs(tmp, nBytesReceived));
                    }
    
                    Array.Clear(this.ByteBuffer, 0, this.ByteBuffer.Length);
                    if (this.client.Connected == true)
                    {
    		    //Hier kommt die Funktion nicht mehr hin
                        this.client.BeginReceive(this.byteBuffer, 0, InputBufferSize, SocketFlags.None, this.ReadCallback, null);
                    }
                    else
                    {
    		    //Hier kommt die Funktion nicht mehr hin
                        this.DisConnect();
                    }
    		//Hier kommt die Funktion nicht mehr hin
    
                }
                catch (Exception ex)
                {
    		//Hier kommt die Funktion nicht mehr hin
    		byte[] byteBuffer = new byte[InputBufferSize];
                    this.ChangeState(WinsockStates.Error);
                    if (this.ConnectionError != null)
                    {
                        this.ConnectionError(this, new ConnectionErrorEventArgs(ex));
                    }
                }
            }

    Wie ich bereits in meiner ursprünglichen Frage angemerkt habe verwenden wir diesen Quelltext in vielen Schnittstellen... bisher ohne Probleme.


    Mit freundlichen Grüßen / Best Regards Thomas



    Mittwoch, 11. April 2012 14:33
  • Thomas,

    Ein blockieren in EndReceive scheint mir recht aussergewöhnlich, deutet eher darauf hin dass zuvor etwas 'ungesundes' mit Socket/Threads/CLR angestellt wurde.
    Ich würde eine Kopie dieses Projekts mal auf das notwendigste reduzieren und nochmals prüfen.
    Daneben bieten .NET Sockets selber auch ein Logging/Tracing:
    Network Tracing
    http://msdn.microsoft.com/en-us/library/hyb3xww8.aspx

    PS: beachte bei 'Testausgaben in eine Datei', .NET/Windows buffert Dateienausgaben, ggf wurden letzte Einträge gar noch nicht geschrieben.

    Mittwoch, 11. April 2012 23:55
  • ****************************************************************************************************************
    Dieser Thread wurde mangels weiterer Beteiligung des Fragestellenden ohne bestätigte Lösung abgeschlossen.
    Neue Rückfragen oder Ergänzungen zu diesem Thread bleiben weiterhin möglich.
    ****************************************************************************************************************

    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Montag, 30. April 2012 12:43
    Moderator