Eine bestehende Verbindung wurde vom Remote-Host zwangsweise geschlossen

158

Ich arbeite mit einer kommerziellen Anwendung, die eine SocketException mit der Nachricht auslöst.

Eine bestehende Verbindung wurde vom Remote-Host zwangsweise geschlossen

Dies geschieht bei einer Socket-Verbindung zwischen Client und Server. Die Verbindung ist lebendig und gut, und es werden Datenmengen übertragen, die dann jedoch aus dem Nichts getrennt werden.

Hat das schon mal jemand gesehen? Was könnten die Ursachen sein? Ich kann ein paar Ursachen erraten, aber gibt es auch eine Möglichkeit, mehr in diesen Code einzufügen, um herauszufinden, was die Ursache sein könnte?

Kommentare / Ideen sind willkommen.

... Das Neueste ...

Ich habe einige Protokolle von einer .NET-Ablaufverfolgung,

System.Net.Sockets Verbose: 0 : [8188] Socket#30180123::Send() DateTime=2010-04-07T20:49:48.6317500Z

System.Net.Sockets Error: 0 : [8188] Exception in the Socket#30180123::Send - An existing connection was forcibly closed by the remote host DateTime=2010-04-07T20:49:48.6317500Z 

System.Net.Sockets Verbose: 0 : [8188] Exiting Socket#30180123::Send() -> 0#0

Basierend auf anderen Teilen der Protokollierung habe ich die Tatsache gesehen, dass "0 # 0" bedeutet, dass ein Paket mit einer Länge von 0 Bytes gesendet wird. Aber was bedeutet das wirklich?

Eine von zwei Möglichkeiten tritt auf, und ich bin nicht sicher, welche,

1) Die Verbindung wird geschlossen, aber dann werden Daten in den Socket geschrieben, wodurch die obige Ausnahme entsteht. Die 0 # 0 bedeutet einfach, dass nichts gesendet wurde, weil der Socket bereits geschlossen war.

2) Die Verbindung ist noch offen und es wird ein Paket mit null Bytes gesendet (dh der Code hat einen Fehler). Die 0 # 0 bedeutet, dass ein Paket mit null Bytes versucht wird, gesendet zu werden.

Was glaubst du? Es mag nicht schlüssig sein, denke ich, aber vielleicht hat jemand anderes so etwas gesehen?

Peter
quelle
Nur ein Update. Es scheint, dass wireshark es in diesem Fall aufgrund unseres Netzwerk-Setups nicht schneiden wird. Aber ich werde es hoffentlich versuchen, blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx, das mit .NET verfolgt, das einige Protokolldateien erzeugen sollte. Ich werde Sie auf dem
Laufenden
1
Es ist auch bekannt, dass Comcast "Null" -Pakete sendet, die mit einer gefälschten ID gefälscht sind, um sich mit dem P2P-Verkehr

Antworten:

98

Dies bedeutet im Allgemeinen, dass die Remote-Seite die Verbindung geschlossen hat (normalerweise durch Senden eines TCP / IP- RSTPakets). Wenn Sie mit einer Drittanbieteranwendung arbeiten, sind die folgenden Ursachen wahrscheinlich:

  • Sie senden fehlerhafte Daten an die Anwendung (einschließlich des Sendens einer HTTPS-Anforderung an einen HTTP-Server).
  • Die Netzwerkverbindung zwischen Client und Server wird aus irgendeinem Grund unterbrochen
  • Sie haben einen Fehler in der Drittanbieteranwendung ausgelöst, der zum Absturz geführt hat
  • Die Drittanbieteranwendung hat die Systemressourcen erschöpft

Es ist wahrscheinlich, dass der erste Fall ist, was passiert.

Sie können Wireshark starten , um genau zu sehen, was auf dem Draht passiert, um das Problem einzugrenzen.

Ohne genauere Informationen ist es unwahrscheinlich, dass Ihnen hier jemand wirklich viel helfen kann.

RarrRarrRarr
quelle
2
Toll. Vielen Dank. Das andere an Wireshark. Es sammelt so viele Daten, wie könnte ich so etwas herausfiltern? Wenn wireshark etwas auftaucht, könnte ich es später hier posten ...
Peter
4
Sie sollten in der Lage sein, den Wireshark-Speicherauszug mindestens nach IP-Adresse und Portnummer zu filtern. Danach ist es wahrscheinlich am hilfreichsten, sich das Ende des Streams anzusehen (wo etwas schief gelaufen ist) und rückwärts zu arbeiten, bis Sie erkennen können, wo die Dinge zuerst durcheinander geraten. Abhängig von der Komplexität des
betreffenden
4
Gibt es eine Quelle für die Aufzählungszeichen oder hat die Antwort des Spielers unten nur Ihre Liste kopiert?
Zack
7
Bitte beachten Sie, dass "Senden fehlerhafter Daten" das Senden einer httpsAnfrage an einen httpServer bedeuten kann und wahrscheinlich auch umgekehrt.
AXMIM
2
In meinem Fall wurde diese Ausnahme nur beim Aufrufen einer API beim lokalen Ausführen der App angezeigt. Keine Probleme in Entwicklungs-, Qa- oder Produktumgebungen. Die Reparatur? Lokale Verwendung von http anstelle von https. Wir glauben, dass dies möglicherweise mit einem Load Balancer zusammenhängt. Aber wir haben gerade unsere dev.qa und prod web.configs mit Transformationen für https aktualisiert. Problem gelöst.
Kershaw
82

Die Verwendung von TLS 1.2 hat diesen Fehler behoben.
Sie können Ihre Anwendung mit TLS 1.2 damit erzwingen (stellen Sie sicher, dass Sie sie ausführen, bevor Sie Ihren Dienst aufrufen):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Eine andere Lösung:
Aktivieren Sie eine starke Kryptografie auf Ihrem lokalen Computer oder Server, um TLS1.2 zu verwenden, da diese standardmäßig deaktiviert ist und nur TLS1.0 verwendet wird.
Führen Sie diese Befehle in PowerShell mit Administratorrechten aus, um eine starke Kryptografie zu ermöglichen:

Set-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\.NetFramework\v4.0.30319' -Name 'SchUseStrongCrypto' -Value '1' -Type DWord 

Sie müssen Ihren Computer neu starten, damit diese Änderungen wirksam werden.

Willmaz
quelle
1
Sie können mehrere Werte addieren, um mehrere Protokolle zu unterstützen. Um alles von SSL3 bis TLS1.2 zu unterstützen, setzen Sie SecurityProtocol = (SecurityProtocolType) 4080.
Abacus
29

Dies ist kein Fehler in Ihrem Code. Es stammt aus der Socket-Implementierung von .Net. Wenn Sie die überladene Implementierung von EndReceive wie folgt verwenden, wird diese Ausnahme nicht angezeigt.

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }
Cagatay
quelle
1
Dies kommt vom Betriebssystem und letztendlich vom Peer. Weitere Erklärung ist für die Behauptung erforderlich, dass es sich um einen Softwarefehler handelt.
Marquis von Lorne
5
+1. In meinem C # -Programm habe ich mir den Kopf zerbrochen, warum EndReceiveeine Ausnahme ausgelöst wird, wenn eine ordnungsgemäße Client-Kündigung vorliegt. Wusste nicht, dass dies beabsichtigt ist. Ich finde es schlecht, Ausnahmen in normalen Code-Flows auszulösen. Gott sei Dank für die überladene Methode.
Pavan Manjunath
2
@MSaudi Dies verwendet einen asynchronen Aufruf. Stellen Sie sicher, dass Ihr Code nicht stoppt, während er die zurückgegebenen Daten verarbeitet. Beispiel verwendet msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx . Grundsätzlich müssen Sie eine StateObjectKlasse mit public byte[] buffer = new byte[1024], public Socket socket;einer aufgerufenen Funktion haben und diese aufrufen Receive(Socket s), die dies tut StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); und in der void ReceiveCallback(IAsyncResult ar)Sie diesen Code oben aufrufen.
Vapcguy
2
@cagatay Obwohl es eine Lösung bietet, habe ich bei asynchronen Methoden, bei denen Sie sofort wissen müssen, was nach Ihrer Ausführung zurückkommt, nie einen Wert gesehen, Sendbevor Sie etwas anderes tun können.
Vapcguy
3
Eigentlich habe ich festgestellt, dass diese Methode nicht kinderleicht ist. Es kann auch den OP-Fehler verursachen: stackoverflow.com/questions/17790612/…
vapcguy
10

Einfache Lösung für dieses häufig auftretende nervige Problem:

Gehen Sie einfach zu Ihrer Datei " .context.cs" (unter " .context.tt", die sich unter Ihrer Datei "* .edmx" befindet).

Fügen Sie dann diese Zeile Ihrem Konstruktor hinzu:

public DBEntities() 
        : base("name=DBEntities") 
    { 
        this.Configuration.ProxyCreationEnabled = false; // ADD THIS LINE !
    }

hoffe das ist hilfreich.

ayheber
quelle
@Esi wo soll man das hinstellen? und kein Rückgabetyp?
Khalil Khalaf
2
@FirstStep: Weil dies ein Konstruktor ist.
Nikhil Agrawal
3
Dies hilft nur denjenigen, die Entity Framework verwenden, bei denen das Problem auftritt, nicht denjenigen, die socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);die zurückgegebenen Bytes einfach lesen, was das Problem des OP war.
Vapcguy
wenn ENTITY FRAMEWORKnur diese Lösung funktioniert !!! nur das ! danke Bruder :)
Rao Hammas
9

Hatte den gleichen Fehler. Funktionierte tatsächlich, falls der Datenverkehr über einen Proxy gesendet wurde (in meinem Fall Geiger). Das .NET Framework wurde von 4.5.2 auf> = 4.6 aktualisiert und jetzt funktioniert alles einwandfrei. Die eigentliche Anfrage war:
new WebClient().DownloadData("URL");
Die Ausnahme war:

SocketException: Eine vorhandene Verbindung wurde vom Remote-Host zwangsweise geschlossen

0x49D1
quelle
5
Dies war eine Möglichkeit, Dinge für mich zu lösen. Es hing tatsächlich damit zusammen, welche Version von TLS .NET standardmäßig verwendet wurde. 4.5.2 und niedriger verwendet TLS 1.0, während 4.6 und höher klüger sind, wenn es darum geht, 1.1 und 1.2 zuzulassen. Dies wurde auch bewiesen, indem die TLS-Anforderung auf dem Server auf 1.0 gesenkt wurde, wodurch das Problem ebenfalls behoben wurde.
HotN
4

Ich habe diese Ausnahme aufgrund eines Zirkelverweises in der Entität. In der Entität, die aussieht wie

public class Catalog
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public Catalog Parent { get; set; }
    public ICollection<Catalog> ChildCatalogs { get; set; }
}

Ich habe [IgnoreDataMemberAttribute] zur Parent-Eigenschaft hinzugefügt. Und das hat das Problem gelöst.

Bazaleev Nikolay
quelle
2

Bei Ausführung in einem .Net 4.5.2-Dienst

Für mich verschärfte sich das Problem, weil der Anruf in einem .Net 4.5.2-Dienst ausgeführt wurde. Ich folgte dem Vorschlag von @willmaz, bekam aber einen neuen Fehler.

Beim Ausführen des Dienstes mit aktivierter Protokollierung habe ich festgestellt, dass das Handshake mit der Zielwebsite in Ordnung ist (und das Inhaber-Token sendet), aber im folgenden Schritt zum Verarbeiten des Post-Aufrufs scheint das Authentifizierungstoken gelöscht zu werden, und die Site würde dies tun antworte mit Unauthorized.

Es stellte sich heraus, dass die Anmeldeinformationen des Servicepools keine Rechte zum Ändern von TLS (?) Hatten, und als ich mein lokales Administratorkonto in den Pool einfügte, funktionierte alles.

ΩmegaMan
quelle
2

Für alle, die diese Ausnahme beim Lesen von Daten aus dem Stream erhalten, kann dies hilfreich sein. Ich habe diese Ausnahme beim Lesen der HttpResponseMessage in einer Schleife wie der folgenden erhalten:

using (var remoteStream = await response.Content.ReadAsStreamAsync())
using (var content = File.Create(DownloadPath))
{
    var buffer = new byte[1024];
    int read;

    while ((read = await remoteStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
    {
        await content.WriteAsync(buffer, 0, read);
        await content.FlushAsync();
    }
}

Nach einiger Zeit stellte ich fest, dass der Schuldige die Puffergröße war, die zu klein war und mit meiner schwachen Azure-Instanz nicht gut spielte. Was half, war, den Code zu ändern in:

using (Stream remoteStream = await response.Content.ReadAsStreamAsync())
using (FileStream content = File.Create(DownloadPath))
{
    await remoteStream.CopyToAsync(content);
}

Die CopyTo () -Methode hat eine Standardpuffergröße von 81920. Der größere Puffer beschleunigte den Prozess und die Fehler wurden sofort gestoppt, höchstwahrscheinlich, weil die Gesamtdownloadgeschwindigkeit gestiegen ist. Aber warum sollte die Downloadgeschwindigkeit eine Rolle spielen, um diesen Fehler zu verhindern?

Es ist möglich, dass Sie vom Server getrennt werden, da die Download-Geschwindigkeiten unter den Mindestschwellenwert fallen, für den der Server konfiguriert ist. Wenn beispielsweise die Anwendung, von der Sie die Datei herunterladen, auf IIS gehostet wird, kann dies ein Problem mit der Konfiguration von http.sys sein:

"Http.sys ist der http-Protokollstapel, den IIS zur Durchführung der http-Kommunikation mit Clients verwendet. Er verfügt über einen Timer namens MinBytesPerSecond, der für das Beenden einer Verbindung verantwortlich ist, wenn die Übertragungsrate unter einen Schwellenwert von kb / s fällt. Standardmäßig ist dieser Schwellenwert auf 240 kb / s eingestellt. "

Das Problem wird in diesem alten Blogpost des TFS-Entwicklungsteams beschrieben und betrifft speziell IIS, kann Sie jedoch in die richtige Richtung weisen. Es wird auch ein alter Fehler erwähnt, der mit diesem http.sys-Attribut zusammenhängt: link

Wenn Sie Azure-App-Dienste verwenden und das Problem durch Erhöhen der Puffergröße nicht behoben werden kann, versuchen Sie auch, Ihren Computer zu skalieren. Sie erhalten mehr Ressourcen einschließlich der Verbindungsbandbreite.

Andrej Lucansky
quelle
0

Ich hatte das gleiche Problem und konnte es schließlich lösen. In meinem Fall war an den Port, an den der Client die Anforderung sendet, kein SSL-Zertifikat gebunden. Also habe ich das Problem behoben, indem ich ein SSL-Zertifikat an den Port auf der Serverseite gebunden habe. Sobald dies erledigt war, verschwand diese Ausnahme.

iefgnoix
quelle
-1

Dieser Fehler trat in meiner Anwendung mit dem CIP-Protokoll immer dann auf, wenn ich in weniger als 10 Sekunden keine Daten gesendet oder empfangen habe.

Dies wurde durch die Verwendung der Forward-Open-Methode verursacht. Sie können dies vermeiden, indem Sie mit einer anderen Methode arbeiten oder eine Aktualisierungsrate von weniger als 10 Sekunden installieren, um Ihre Forward-Open-Verbindung aufrechtzuerhalten.

Belekz
quelle