Fragensteller
TCP Verbindung hört auf zu empfangen

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
- Bearbeitet Thomas_21224 Dienstag, 10. April 2012 15:32
- Typ geändert Robert BreitenhoferModerator Montag, 30. April 2012 12:43 Keine Rückmeldung des Fragenstellender
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=226775Generell:
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). -
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
-
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? Letzteresarbeitet mit BeginRead und einer Callback-Funktion. Und ist auf jedenFall zu bevorzugen. Hier mal aus dem Zusammenhang gerissen eine CallbackFunktion, 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 hostInvoke(new Action(DoDisconnect));else// Other exception occuredMessageBox.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
-
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
- Bearbeitet Thomas_21224 Mittwoch, 11. April 2012 14:36
-
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.aspxPS: beachte bei 'Testausgaben in eine Datei', .NET/Windows buffert Dateienausgaben, ggf wurden letzte Einträge gar noch nicht geschrieben.
-
****************************************************************************************************************
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
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.