Daten von der Transportverbindung können nicht gelesen werden: Eine vorhandene Verbindung wurde vom Remote-Host zwangsweise geschlossen

103

Ich habe eine Server-App und manchmal, wenn der Client versucht, eine Verbindung herzustellen, wird folgende Fehlermeldung angezeigt:

Geben Sie hier die Bildbeschreibung ein

HINWEIS: Der Text "Stream vom Client konnte nicht abgerufen werden oder Anmeldung fehlgeschlagen" ist ein Text, den ich in der catch-Anweisung hinzugefügt habe

und die Zeile, an der es stoppt (sThread: Zeile 96), ist:

tcpClient = (TcpClient)client;
clientStream = tcpClient.GetStream();
sr = new StreamReader(clientStream);
sw = new StreamWriter(clientStream);

// line 96:                 
a = sr.ReadLine();

Was kann dieses Problem verursachen? Beachten Sie, dass dies nicht immer der Fall ist

Alex
quelle

Antworten:

62

Dieser Fehler bedeutet normalerweise, dass der Zielcomputer ausgeführt wird, der Dienst, zu dem Sie eine Verbindung herstellen möchten, jedoch nicht verfügbar ist. (Entweder ist es gestoppt, abgestürzt oder es ist mit einer anderen Anforderung beschäftigt.)

Auf Englisch: Die Verbindung zum Computer (Remote-Host / Server / PC, auf dem der Dienst ausgeführt wird) wurde hergestellt. Da der Dienst auf diesem Computer jedoch nicht verfügbar war , wusste der Computer nicht, was mit der Anforderung zu tun ist.

Wenn die Verbindung zum Computer nicht verfügbar war, wird ein anderer Fehler angezeigt. Ich habe vergessen, was es ist, aber es ist im Sinne von "Service nicht erreichbar" oder "Nicht verfügbar".

Bearbeiten - hinzugefügt

Es ist möglich, dass dies durch eine Firewall verursacht wird, die den Port blockiert. Angesichts der Tatsache, dass Sie sagen, dass diese zeitweise auftritt ("manchmal, wenn der Client versucht, eine Verbindung herzustellen"), ist dies sehr unwahrscheinlich. Ich habe das ursprünglich nicht aufgenommen, weil ich es mental ausgeschlossen hatte, bevor ich antwortete.

David
quelle
1
Die Sache ist, dass beim Starten des Servers etwa 50 Clients eine Verbindung zu meinem Server herstellen. Ich habe eine Art Wartesignal implementiert, wenn ich einen Client akzeptiere. So etwas wie while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); ajutor ++; } client = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... und Program.waitToFinishAtClient wird in dem Thread geändert, der den Client enthält
Alex
Könnte dieses "Warten" das Problem sein?
Alex
1
soll ich es einfach sein lassen nein warten?
Alex
1
Ich denke das Warten ist das Problem. Ich weiß nicht genug von Ihrem Code, um sicher zu sein, aber das klingt wahrscheinlich. Nur neugierig, ob Sie Ihren eigenen Service auf die "harte Tour" aufgebaut haben oder ob Sie WCF oder sogar Remoting dafür verwenden ...
David
Aufgrund der kleinen Menge an Code hier scheint es mir, dass das "Warten" -Problem vermieden werden könnte, wenn es sich für jede Verbindung in einem separaten Thread befindet. Nur für den Fall, dass diese Vermutung richtig ist, hier ein Beispiel für einen Multithread-TCP-Dienst mit Multithreading, der Ihnen helfen kann: switchonthecode.com/tutorials/…
David
180

Ich habe diesen Fehler beim Aufrufen eines Webdienstes erhalten. Das Problem betraf auch die Sicherheit auf Transportebene. Ich könnte den Webdienst über ein Website-Projekt aufrufen, aber wenn ich denselben Code in einem Testprojekt wiederverwenden würde, würde ich eine WebException erhalten, die diese Nachricht enthält. Durch Hinzufügen der folgenden Zeile vor dem Anruf wurde das Problem behoben:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Bearbeiten

System.Net.ServicePointManager.SecurityProtocol - Diese Eigenschaft wählt die Version des SSL- (Secure Sockets Layer) oder TLS-Protokolls (Transport Layer Security) aus, die nur für neue Verbindungen verwendet werden soll, die nur das HTTPS-Schema (Secure Hypertext Transfer Protocol) verwenden. Bestehende Verbindungen werden nicht geändert.

Ich glaube, dass die SecurityProtocolKonfiguration während des TLS-Handshakes bei der Auswahl der Protokollversion wichtig ist.

TLS-Handshake - Mit diesem Protokoll werden alle Informationen ausgetauscht, die beide Seiten für den Austausch der tatsächlichen Anwendungsdaten durch TLS benötigen.

ClientHello - Ein Client sendet eine ClientHello-Nachricht mit der Angabe der höchsten unterstützten TLS-Protokollversion ...

ServerHello - Der Server antwortet mit einer ServerHello-Nachricht, die die ausgewählte Protokollversion enthält ... Die ausgewählte Protokollversion sollte die höchste sein, die sowohl vom Client als auch vom Server unterstützt wird. Wenn der Client beispielsweise TLS Version 1.1 und der Server Version 1.2 unterstützt, sollte Version 1.1 ausgewählt werden. Version 1.2 sollte nicht ausgewählt werden.

Hans Vonn
quelle
8
das hat mich gerettet! Danke, Mann. In meinem Debugger versuche ich, während des Testens einen https-Dienst aufzurufen, und hatte das Problem, das das OP hatte.
Blair Holmes
6
Wissen wir mehr darüber, wie / warum das funktioniert? Ich habe mit einem PostAsync-Aufruf zu kämpfen, und dies scheint auch meinen Fehler zu beheben. Ich bin froh, dass es funktioniert hat, aber ich würde auch gerne wissen warum.
Kevin Matlock
1
@ HansVonn Danke dafür! Hat mir eine Menge Zeit gespart - In Bezug darauf, warum es funktioniert Es beschränkt nur die TLS-Version, die Sie beim Herstellen einer Verbindung verwenden.
verwirrt und
1
Ich kann nicht glauben, dass mich das wieder erwischt hat! Vielen Dank
Sergio A.
2
DANKE! Das hat mich verrückt gemacht.
Mknopf
34

Mein spezielles Szenario war, dass für den Azure-Appdienst die minimale TLS-Version auf 1.2 geändert wurde

Ich weiß nicht, ob dies von nun an die Standardeinstellung ist, aber das Zurücksetzen auf 1.0 hat funktioniert.

Sie können auf die Einstellung unter "SSL-Einstellungen" zugreifen.

Hugo Hilário
quelle
7
Oh mein Gott, vielen Dank! Ich habe sooo lange daran festgehalten und die SSL-Einstellungen der Web-App überprüft, und das Minimum wurde auf 1,2 anstelle von 1,0 festgelegt. Als ich es wieder auf 1.0 änderte und die Web-App neu startete, funktionierte es! Ich danke dir sehr!
Mason
1
Vielen Dank, @ hugo-hilário, erstaunlicherweise hat es auch bei mir funktioniert! Wie um alles in der Welt haben Sie es geschafft, eine so knifflige Lösung zu finden! : D
Hosjay
@ Hosjay es war auch eine Hölle für mich :)
Hugo Hilário
3
Rettete meinen Tageskameraden!
Nitesh
Ich hatte dieses Problem für meine Azure-Funktion v2
Pieter Heemeryck
17

Ich bin mir nicht sicher, welche der Korrekturen in diesen Blog-Posts geholfen haben, aber einer von ihnen hat dieses Problem für mich gelöst ...

http://briancaos.wordpress.com/2012/07/06/unable-to-read-data-from-the-transport-connection-the-connection-was-closed/

Der Trick, der mir geholfen hat, war, die Verwendung einer WebRequest zu beenden und stattdessen eine HttpWebRequest zu verwenden. Mit HttpWebRequest kann ich mit 3 wichtigen Einstellungen spielen:

und

http://briancaos.wordpress.com/2012/06/15/an-existing-connection-was-forcibly-closed-by-the-remote-host/

  • SCHRITT 1: Deaktivieren Sie KeepAlive
  • SCHRITT 2: Setzen Sie ProtocolVersion auf Version 10
  • SCHRITT 3: Begrenzen der Anzahl der Servicepunkte
SteveC
quelle
1
Diese Antwort hat das gleiche Problem für mich gelöst. Ich habe 'Keep Alive' im Abschnitt HTTP-Antwort-Header in IIS7 deaktiviert
drzounds
Ich sollte hinzufügen, dass ich diesen Code auch zur Reference.cs für den Webdienst hinzufügen musste, der dieses Verhalten hatte. geschützte Überschreibung System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = false; return webRequest; }
drzounds
11

Bei Aufrufen von HTTPS-Diensten von einem unserer Server wurde außerdem die Ausnahme " Daten können nicht von der Transportverbindung gelesen werden: Eine vorhandene Verbindung wurde zwangsweise geschlossen " ausgelöst. Der HTTP-Dienst funktionierte jedoch einwandfrei. Mit Wireshark wurde festgestellt, dass es sich um einen TLS-Handshake-Fehler handelt. Am Ende musste die Cipher Suite auf dem Server aktualisiert werden.

Jobrocol
quelle
Das ist was mit mir passiert ist. A wurde ein abgelaufenes Zertifikat an eine SSL-Verbindung gesendet. A das Zertifikat erneuern und arbeiten.
Guilherme de Jesus Santos
8

Laut "Hans Vonn" antwortet.

Durch Hinzufügen der folgenden Zeile vor dem Anruf wurde das Problem behoben:

System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

Nach dem Hinzufügen des Sicherheitsprotokolls und der einwandfreien Funktion muss ich jedoch vor jedem API-Aufruf hinzufügen, was nicht fehlerfrei ist. Ich aktualisiere nur die .net Framework-Version mindestens 4.6 und arbeite wie erwartet. Sie muss nicht vor jedem API-Aufruf hinzugefügt werden.

Mahi Uddin
quelle
1
Vielen Dank. du hast meinen Tag gerettet. Für einige könnte es nützlich sein, wenn ich erwähne, dass ich zuvor auch getestet habe, die Firewall zu deaktivieren und ServicePointManager.ServerCertificateValidationCallback hinzuzufügen, aber nicht funktioniert hat.
Tekin
5

Dies hilft nicht bei zeitweiligen Problemen, kann jedoch für andere Personen mit einem ähnlichen Problem hilfreich sein.

Ich hatte eine VM geklont und in einem anderen Netzwerk mit einer neuen IP-Adresse gestartet, aber die Bindungen in IIS nicht geändert. Fiddler zeigte mir "Daten von der Transportverbindung konnten nicht gelesen werden: Eine vorhandene Verbindung wurde vom Remote-Host zwangsweise geschlossen" und der IE sagte mir "TLS 1.0, TLS 1.1 und TLS 1.2 in den erweiterten Einstellungen aktivieren". Das Ändern der Bindung an die neue IP-Adresse hat es für mich gelöst.

Jon.Mozley
quelle
2

Aus irgendeinem Grund wurde die Verbindung zum Server unterbrochen. Es kann sein, dass der Server die Verbindung explizit geschlossen hat oder dass ein Fehler auf dem Server dazu geführt hat, dass sie unerwartet geschlossen wurde. Oder etwas zwischen dem Client und dem Server (ein Switch oder Router) hat die Verbindung getrennt.

Möglicherweise hat der Servercode das Problem verursacht, möglicherweise jedoch nicht. Wenn Sie Zugriff auf den Servercode haben, können Sie dort ein Debugging durchführen, um zu erfahren, wann Clientverbindungen geschlossen werden. Dies kann Ihnen einen Hinweis darauf geben, wann und warum Verbindungen getrennt werden.

Auf dem Client müssen Sie Ihren Code schreiben, um die Möglichkeit eines Serverausfalls jederzeit zu berücksichtigen. So ist es halt: Netzwerkverbindungen sind von Natur aus unzuverlässig.

Jim Mischel
quelle
2

Dies löste mein Problem. Ich habe diese Zeile hinzugefügt, bevor die Anfrage gestellt wird:

System.Net.ServicePointManager.Expect100Continue = false;

Es schien, als gäbe es einen Proxy im Weg des Servers, der das 100-Continue-Verhalten nicht unterstützte.

Mahdi Ataollahi
quelle
1

Ich habe dieses Problem in der Vergangenheit. Ich verwende PostgreSQL und wenn ich mein Programm ausführe, stellt es manchmal eine Verbindung her und manchmal wird ein solcher Fehler ausgegeben.

Wenn ich mit meinem Code experimentiere, setze ich meinen Verbindungscode in die allererste Zeile unter dem öffentlichen Formular. Hier ist ein Beispiel:

VOR:

    public Form1()
        {
        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!





        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());
        }

JETZT:

    public Form1()
        {
        //Connect to Database to generate auto number
        NpgsqlConnection iConnect = new NpgsqlConnection("Server=localhost;Port=5432;User ID=postgres;Password=pass;Database=DB");
        iConnect.Open();
        NpgsqlCommand iQuery = new NpgsqlCommand("Select * from table1", iConnect);
        NpgsqlDataReader iRead = iQuery.ExecuteReader();
        NpgsqlDataAdapter iAdapter = new NpgsqlDataAdapter(iQuery);

        DataSet iDataSet = new DataSet();
        iAdapter.Fill(iDataSet, "ID");

        MessageBox.Show(iDataSet.Tables["ID"].Rows.Count.ToString());





        //HERE LIES SOME CODES FOR RESIZING MY CONTROLS DURING RUNTIME
        //CODE
        //CODE AGAIN
        //ANOTHER CODE
        //CODE NA NAMAN
        //CODE PA RIN!

        }

Ich denke, dass das Programm zuerst die Verbindung lesen muss, bevor etwas getan wird. Ich weiß nicht, korrigiere mich, wenn ich falsch liege. Aber meiner Forschung nach ist es kein Codeproblem - es war tatsächlich von der Maschine selbst.

Viel Spaß beim Codieren!

Curbside Coder
quelle
1
System.Net.ServicePointManager.Expect100Continue = false;

Dieses Problem tritt manchmal aufgrund des auf dem Webserver implementierten Proxyservers auf. So umgehen Sie den Proxyserver, indem Sie diese Zeile einfügen, bevor Sie den Sendedienst aufrufen.

Tahir Alvi
quelle
0

Ich hatte eine Drittanbieteranwendung (Fiddler) ausgeführt, um zu versuchen, die gesendeten Anforderungen zu sehen. Das Schließen dieser Anwendung hat das Problem für mich behoben

Johan Aspeling
quelle
0

Wir hatten ein sehr ähnliches Problem, bei dem die Website eines Kunden versuchte, eine Verbindung zu unserem Web-API-Dienst herzustellen und dieselbe Nachricht zu erhalten. Dies geschah völlig aus heiterem Himmel, als auf dem Server, auf dem IIS ausgeführt wurde, keine Codeänderungen oder Windows-Updates vorgenommen wurden.

In unserem Fall stellte sich heraus, dass die aufrufende Website eine Version von .Net verwendete, die nur TLS 1.0 unterstützte, und aus irgendeinem Grund schien der Server, auf dem unser IIS ausgeführt wurde, keine TLS 1.0-Anrufe mehr anzunehmen. Um zu diagnostizieren, dass wir TLS explizit über die Registrierung auf dem IIS-Server aktivieren mussten, mussten wir diesen Server neu starten. Dies sind die Registrierungsschlüssel:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
    1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

If that doesn't do it, you could also experiment with adding the entry for SSL 2.0:


    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
    "DisabledByDefault"=dword:00000000
    "Enabled"=dword:00000001

Meine Antwort auf eine andere Frage hier enthält dieses Powershell-Skript, mit dem wir die Einträge hinzugefügt haben:

HINWEIS: Das Aktivieren alter Sicherheitsprotokolle ist keine gute Idee. In unserem Fall bestand die richtige Antwort darin, die Client-Website zu veranlassen, den Code für die Verwendung von TLS 1.2 zu aktualisieren. Die obigen Registrierungseinträge können jedoch zunächst zur Diagnose des Problems beitragen.

tomRedox
quelle
0

Der Grund, warum mir dies passiert ist, war, dass ich eine rekursive Abhängigkeit in meinem DI-Anbieter hatte. In meinem Fall hatte ich:

services.AddScoped(provider => new CfDbContext(builder.Options));
services.AddScoped(provider => provider.GetService<CfDbContext>());

Das Problem bestand darin, nur die zweite Registrierung für den Dienst mit Gültigkeitsbereich zu entfernen

services.AddScoped(provider => new CfDbContext(builder.Options));
Madison Haynie
quelle
0

Wenn Sie ein https-Zertifikat in der Domäne haben, stellen Sie sicher, dass die https-Bindung an den Domänennamen in IIS gebunden ist. In IIS -> Wählen Sie Ihre Domain aus -> Klicken Sie auf Bindings. Das Site Bindings-Fenster wird geöffnet. Fügen Sie eine Bindung für https hinzu.

user2147447
quelle
0

Hatte ein ähnliches Problem und bekam die folgenden Fehler, abhängig davon, welche App ich verwendet habe und ob wir den Firewall / Load Balancer umgangen haben oder nicht:

HTTPS-Handshake an [blah] (für # 136) ist fehlgeschlagen. System.IO.IOException Daten von der Transportverbindung können nicht gelesen werden: Eine vorhandene Verbindung wurde vom Remote-Host zwangsweise geschlossen

und

ReadResponse () fehlgeschlagen: Der Server hat keine vollständige Antwort auf diese Anforderung zurückgegeben. Der Server hat 0 Bytes zurückgegeben.

Das Problem stellte sich heraus, dass das SSL-Serverzertifikat übersehen wurde und nicht auf einigen Servern installiert war.

tödlicher Hund
quelle
0

Versuchen Sie zu überprüfen, ob Sie überhaupt einen Handschlag herstellen können. Ich hatte dieses Problem bereits beim Hochladen einer Datei und stellte nur fest, dass das Problem die nicht vorhandene Route war, als ich den Upload entfernte und überprüfte, ob er sich mit den Parametern anmelden kann.

Raffy
quelle
0

Für mich war es ein Problem, bei dem in der IIS-Bindung die IP-Adresse des Webservers angegeben war. Ich habe es geändert, um alle nicht zugewiesenen IPs zu verwenden, und meine Anwendung hat begonnen zu funktionieren.

Shivaram Gopalakrishnan
quelle
0

Ich habe den Fehler festgestellt, dass python clr mit adomd eine mdx-Abfrage an Microsoft-Analysedienste ausführt

Ich habe es mit Hilfe von Hans Vonn gelöst und hier ist die Python- Version:

clr.AddReference("System.Net")
from System.Net import ServicePointManager, SecurityProtocolType 
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls
Peter Kazmir
quelle
0

Für diejenigen, die dies später nach .NET Version 4.6 finden könnten, stieß ich ebenfalls auf dieses Problem.

Stellen Sie sicher, dass Sie Ihre web.config-Datei auf folgende Zeilen überprüfen:

<compilation debug="true" targetFramework="4.5">
...
<httpRuntime targetFramework="4.5" />

Wenn Sie 4.6.x oder eine höhere Version von .NET auf dem Server ausführen, stellen Sie sicher, dass Sie diese targetFramework-Werte an die Version des Frameworks auf Ihrem Server anpassen. Wenn Ihre Versionen weniger als 4.6.x lesen, würde ich empfehlen, .NET zu aktualisieren und die neuere Version zu verwenden, es sei denn, Ihr Code ist von einer älteren Version abhängig (in diesem Fall sollten Sie eine Aktualisierung in Betracht ziehen).

Ich habe das targetFrameworks auf 4.7.2 geändert und das Problem ist verschwunden:

<compilation debug="true" targetFramework="4.7.2">
...
<httpRuntime targetFramework="4.7.2" />

Die neueren Frameworks lösen dieses Problem, indem sie das beste verfügbare Protokoll verwenden und unsichere oder veraltete blockieren. Wenn der Remote-Dienst, zu dem Sie eine Verbindung herstellen oder den Sie anrufen möchten, diesen Fehler ausgibt, unterstützt er möglicherweise die alten Protokolle nicht mehr.

Zachary Weber
quelle