No se pueden leer los datos de la conexión de transporte: el host remoto cerró a la fuerza una conexión existente

103

Tengo una aplicación de servidor y, a veces, cuando el cliente intenta conectarse, aparece el siguiente error:

ingrese la descripción de la imagen aquí

NOTA: "No se pudo obtener la transmisión del cliente o el inicio de sesión falló" es un texto que agrego en la declaración de captura

y la línea en la que se detiene (sThread: línea 96) es:

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

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

¿Qué puede estar causando este problema? Tenga en cuenta que no sucede todo el tiempo.

Alex
fuente

Respuestas:

63

Este error generalmente significa que la máquina de destino se está ejecutando, pero el servicio al que está intentando conectarse no está disponible. (Se detuvo, se bloqueó o está ocupado con otra solicitud).

En inglés: Se realizó la conexión a la máquina (host / servidor / PC remoto en el que se ejecuta el servicio), pero como el servicio no estaba disponible en esa máquina, la máquina no sabía qué hacer con la solicitud.

Si la conexión a la máquina no estuviera disponible, vería un error diferente. Olvidé lo que es, pero está en la línea de "Servicio inalcanzable" o "No disponible".

Editar - agregado

ES posible que esto sea causado por un firewall que bloquea el puerto, pero dado que usted dice que es intermitente ("a veces cuando el cliente intenta conectarse"), eso es muy poco probable. No incluí eso originalmente porque lo había descartado mentalmente antes de responder.

David
fuente
1
el caso es que cuando enciendo el servidor hay unos 50 clientes que se conectan a mi servidor. Implementé una especie de señal de espera al aceptar un cliente ... algo como while (Program.waitToFinishLoginAtClient == true && ajutor <30) {Thread.Sleep (300); ajutor ++; } cliente = this.tcpListener.AcceptTcpClient (); Program.waitToFinishLoginAtClient = true; ........... y Program.waitToFinishAtClient se modifica en el hilo que contiene el cliente
Alex
¿Podría ser este "esperar" el problema?
Alex
1
¿Debería dejarlo ser? no, espera ?
Alex
1
Creo que la espera es el problema. No sé lo suficiente de su código para estar seguro, pero seguro que parece probable. Solo tengo curiosidad por saber si creó su propio servicio de la "manera difícil" o si está usando WCF o incluso Remoting para esto ...
David
Basado en el pequeño detalle de código aquí, me parece que el problema de "esperar" podría evitarse si estuviera dentro de un hilo separado para cada conexión. En caso de que esa suposición sea correcta, aquí hay un ejemplo de un servicio TCP de subprocesos múltiples con subprocesos múltiples que puede ayudarlo: switchonthecode.com/tutorials/…
David
180

Recibí este error al llamar a un servicio web. El problema también estaba relacionado con la seguridad del nivel de transporte. Podría llamar al servicio web a través de un proyecto de sitio web, pero al reutilizar el mismo código en un proyecto de prueba, obtendría una WebException que contenía este mensaje. Agregar la siguiente línea antes de realizar la llamada resolvió el problema:

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

Editar

System . las conexiones existentes no se modifican.

Creo que la SecurityProtocolconfiguración es importante durante el protocolo de enlace TLS al seleccionar la versión del protocolo.

Apretón de manos TLS : este protocolo se utiliza para intercambiar toda la información requerida por ambas partes para el intercambio de los datos reales de la aplicación por TLS.

ClientHello : un cliente envía un mensaje ClientHello especificando la versión de protocolo TLS más alta que admite ...

ServerHello : el servidor responde con un mensaje ServerHello, que contiene la versión de protocolo elegida ... La versión de protocolo elegida debe ser la más alta que admitan tanto el cliente como el servidor. Por ejemplo, si el cliente admite TLS versión 1.1 y el servidor admite la versión 1.2, se debe seleccionar la versión 1.1; la versión 1.2 no debe seleccionarse.

Hans Vonn
fuente
8
esto me salvó! gracias hombre. en mi depurador estoy tratando de llamar a un servicio https durante la prueba y tenía el problema que tenía el OP.
Blair Holmes
6
¿Sabemos más sobre cómo / por qué funciona esto? He estado luchando con una llamada PostAsync y esto también parece solucionar mi error. Me alegro de que haya funcionado, pero también me gustaría saber por qué.
Kevin Matlock
1
@HansVonn ¡Gracias por esto! Me ahorró un montón de tiempo: en cuanto a por qué funciona, solo está limitando la versión de TLS que está utilizando cuando se conecta.
confusedandamused
1
¡No puedo creer que esto me atrapó una vez más! Gracias
Sergio A.
2
¡GRACIAS! Esto me estaba volviendo loco.
mknopf
34

Mi escenario de caso específico fue que el servicio de aplicaciones de Azure tenía la versión mínima de TLS cambiada a 1.2

No sé si ese es el valor predeterminado de ahora en adelante, pero volver a cambiarlo a 1.0 lo hizo funcionar.

Puede acceder a la configuración dentro de "Configuración de SSL".

Hugo Hilário
fuente
7
¡Dios mío, MUCHAS GRACIAS! He estado atascado en esto durante tanto tiempo, y verifiqué la configuración de SSL de la aplicación web, y el mínimo se estableció en 1.2 en lugar de 1.0. Cuando lo cambié de nuevo a 1.0 y reinicié la aplicación web, ¡funcionó! Muchas gracias!
Mason
1
Muchas gracias, @ hugo-hilário, ¡sorprendentemente también funcionó para mí! ¡Cómo diablos te las arreglaste para encontrar una solución tan complicada! : D
hosjay
@hosjay fue un infierno para mí también :)
Hugo Hilário
3
¡Salvó a mi compañero de día!
Nitesh
Tuve este problema para mi función Azure v2
Pieter Heemeryck
17

No estoy seguro de cuál de las correcciones en estas publicaciones de blog ayudó, pero una de ellas solucionó este problema por mí ...

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

El truco que me ayudó fue dejar de usar WebRequest y usar HttpWebRequest en su lugar. HttpWebRequest me permite jugar con 3 configuraciones importantes:

y

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

  • PASO 1: Desactive KeepAlive
  • PASO 2: Establezca ProtocolVersion en Version10
  • PASO 3: Limitar el número de puntos de servicio
SteveC
fuente
1
Esta respuesta es lo que me resolvió este mismo problema.
Apagué
Debo agregar que también tuve que agregar este código a Reference.cs para el servicio web que tenía ese comportamiento. anulación protegida System.Net.WebRequest GetWebRequest (Uri uri) {System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest) base.GetWebRequest (uri); webRequest.KeepAlive = falso; return webRequest; }
drzounds
11

Las llamadas a los servicios HTTPS desde uno de nuestros servidores también arrojaban la excepción " No se pueden leer los datos de la conexión de transporte: una conexión existente se cerró a la fuerza ". El servicio HTTP, sin embargo, funcionó bien. Se usó Wireshark para comprobar que se trataba de una falla en el protocolo de enlace TLS. Terminó siendo que el conjunto de cifrado en el servidor necesitaba actualizarse.

Jobrocol
fuente
Esto es lo que me estaba pasando. Se envió un certificado caducado a una conexión SSL. A renovar el certificado y funcionó.
Guilherme de Jesus Santos
8

Según responde "Hans Vonn".

Agregar la siguiente línea antes de realizar la llamada resolvió el problema:

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

Después de agregar el protocolo de seguridad y funciona bien, pero tengo que agregar antes de cada llamada de API que no sea saludable. Acabo de actualizar la versión de .net framework al menos 4.6 y funcionando como se esperaba no es necesario agregar antes de cada llamada a la API.

Mahi Uddin
fuente
1
Muchas gracias. me has alegrado el día. Podría ser útil para algunos si menciono que antes de esto también probé desactivando el firewall y agregando ServicePointManager.ServerCertificateValidationCallback pero no funcionó.
Tekin
5

Esto no ayudará para problemas intermitentes, pero puede ser útil para otras personas con un problema similar.

Había clonado una máquina virtual y la había iniciado en una red diferente con una nueva dirección IP, pero no había cambiado los enlaces en IIS. Fiddler me mostraba "No se pueden leer datos de la conexión de transporte: el host remoto cerró a la fuerza una conexión existente" e IE me decía "Activar TLS 1.0, TLS 1.1 y TLS 1.2 en la configuración avanzada". Cambiar el enlace a la nueva dirección IP lo resolvió para mí.

Jon.Mozley
fuente
2

Por alguna razón, se perdió la conexión con el servidor. Podría ser que el servidor cerró explícitamente la conexión o un error en el servidor hizo que se cerrara inesperadamente. O algo entre el cliente y el servidor (un conmutador o enrutador) cortó la conexión.

Puede que sea el código del servidor el que haya causado el problema, y ​​puede que no lo sea. Si tiene acceso al código del servidor, puede poner un poco de depuración allí para indicarle cuándo se cierran las conexiones del cliente. Eso podría darle alguna indicación de cuándo y por qué se caen las conexiones.

En el cliente, debe escribir su código para tener en cuenta la posibilidad de que el servidor falle en cualquier momento. Así son las cosas: las conexiones de red son intrínsecamente poco fiables.

Jim Mischel
fuente
2

Esto resolvió mi problema. Agregué esta línea antes de realizar la solicitud:

System.Net.ServicePointManager.Expect100Continue = false;

Parecía que había un proxy en el camino del servidor que no admitía el comportamiento 100-continue.

Mahdi Ataollahi
fuente
1

Tengo ese problema en el pasado. Estoy usando PostgreSQL y cuando ejecuto mi programa, a veces se conecta ya veces arroja un error como ese.

Cuando experimento con mi código, pongo mi código de conexión en la primera línea debajo del formulario público. Aquí hay un ejemplo:

ANTES DE:

    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());
        }

AHORA:

    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!

        }

Creo que el programa debe leer primero la conexión antes de hacer nada, no sé, corregirme si me equivoco. Pero según mi investigación, no es un problema de código, en realidad fue de la propia máquina.

¡Feliz codificación!

Codificador de acera
fuente
1
System.Net.ServicePointManager.Expect100Continue = false;

Este problema ocurre en algún momento debido a que el servidor proxy está implementado en el servidor web. Para omitir el servidor proxy colocando esta línea antes de llamar al servicio de envío.

Tahir Alvi
fuente
0

Tenía una aplicación de terceros (Fiddler) ejecutándose para intentar ver las solicitudes enviadas. Cerrar esta aplicación me lo arregló

Johan Aspeling
fuente
0

Tuvimos un problema muy similar en el que el sitio web de un cliente intentaba conectarse a nuestro servicio de API web y recibía el mismo mensaje. Esto comenzó a suceder completamente de la nada cuando no hubo cambios de código o actualizaciones de Windows en el servidor donde se estaba ejecutando IIS.

En nuestro caso, resultó que el sitio web de llamadas estaba usando una versión de .Net que solo admitía TLS 1.0 y, por alguna razón, el servidor donde se estaba ejecutando nuestro IIS parecía haber dejado de aceptar llamadas TLS 1.0. Para diagnosticar eso, tuvimos que habilitar TLS explícitamente a través del registro en el servidor de IIS y luego reiniciar ese servidor. Estas son las claves de registro:

[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

Mi respuesta a otra pregunta aquí tiene este script de PowerShell que usamos para agregar las entradas:

NOTA: Habilitar los protocolos de seguridad antiguos no es una buena idea, la respuesta correcta en nuestro caso fue hacer que el sitio web del cliente actualice su código para usar TLS 1.2, pero las entradas de registro anteriores pueden ayudar a diagnosticar el problema en primer lugar.

tomRedox
fuente
0

La razón por la que esto me estaba sucediendo era que tenía una dependencia recursiva en mi proveedor de DI. En mi caso tuve:

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

La solución fue simplemente eliminar el segundo registro de servicio de ámbito

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

Si tiene un certificado https en el dominio, asegúrese de tener el enlace https al nombre de dominio en IIS. En IIS -> Seleccione su dominio -> Haga clic en Enlaces Se abre la ventana Enlaces de sitios. Agregue un enlace para https.

usuario2147447
fuente
0

Tuve un problema similar y recibí los siguientes errores dependiendo de la aplicación que usé y si omitimos el firewall / balanceador de carga o no:

El protocolo de enlace HTTPS con [blah] (para el # 136) falló. System.IO.IOException No se pueden leer datos de la conexión de transporte: el host remoto cerró a la fuerza una conexión existente

y

ReadResponse () falló: el servidor no devolvió una respuesta completa para esta solicitud. El servidor devolvió 0 bytes.

El problema resultó ser que el Certificado de servidor SSL se perdió y no se instaló en un par de servidores.

perro mortal
fuente
0

Intente verificar si puede establecer un apretón de manos en primer lugar. Tuve este problema antes al cargar un archivo y solo descubrí que el problema era la ruta inexistente cuando eliminé la carga y verifiqué si puede iniciar sesión dados los parámetros.

Raffy
fuente
0

Para mí, fue un problema en el que en el enlace de IIS tenía la dirección IP del servidor web. Lo cambié para usar todas las direcciones IP no asignadas y mi aplicación comenzó a funcionar.

Shivaram Gopalakrishnan
fuente
0

Experimenté el error con python clr ejecutando la consulta mdx a los servicios analíticos de Microsoft usando adomd

Lo resolví con la ayuda de Hans Vonn y aquí está la versión de Python :

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

Para aquellos que puedan encontrar esto más tarde, después de la versión 4.6 de .NET, también me encontré con este problema.

Asegúrese de revisar su archivo web.config para las siguientes líneas:

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

Si está ejecutando 4.6.xo una versión superior de .NET en el servidor, asegúrese de ajustar estos valores de targetFramework para que coincidan con la versión del marco en su servidor. Si sus versiones leen menos de 4.6.x, le recomendaría que actualice .NET y use la versión más nueva a menos que su código dependa de una versión anterior (que, en ese caso, debería considerar actualizarla).

Cambié el targetFrameworks a 4.7.2 y el problema desapareció:

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

Los marcos más nuevos solucionan este problema utilizando el mejor protocolo disponible y bloqueando los inseguros u obsoletos. Si el servicio remoto al que está intentando conectarse o llamar está dando este error, es posible que ya no sean compatibles con los protocolos antiguos.

Zachary Weber
fuente