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

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

enter image description here

NOTA: el “no se pudo obtener la transmisión desde el cliente o el inicio de sesión falló” es un texto que agregué en la statement catch.

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

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

En inglés: la conexión a la máquina (host / servidor / PC remotos a los que se ejecuta el servicio) se realizó pero dado que 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 lo incluí originalmente porque lo descarté mentalmente antes de responder.

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 hacer la llamada resolvió el problema:

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

Editar

System.Net.ServicePointManager.SecurityProtocol : esta propiedad selecciona la versión del protocolo Secure Sockets Layer (SSL) o Transport Layer Security (TLS) para usar con conexiones nuevas que solo usan el esquema de protocolo de transferencia segura de hipertexto (HTTPS); las conexiones existentes no se cambian.

Creo que la configuración de SecurityProtocol es importante durante el handshake de TLS al seleccionar la versión de protocolo.

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

ClientHello : un cliente envía un mensaje de ClientHello que especifica 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 compatible tanto con el cliente como con el servidor. Por ejemplo, si el cliente admite TLS versión 1.1 y el servidor admite la versión 1.2, debe seleccionarse la versión 1.1; la versión 1.2 no debe ser seleccionada.

En mi caso específico, el servicio de la aplicación Azure modificó la versión mínima de TLS 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”.

Las llamadas a los servicios HTTPS desde uno de nuestros servidores también arrojaban la excepción ” No se pudo leer datos de la conexión de transporte: una conexión existente se cerró a la fuerza “. El servicio HTTP, sin embargo, funcionó bien. Usé Wireshark para ver que se trataba de una falla de handshake TLS. Terminó diciendo que la suite de cifrado en el servidor necesitaba ser actualizada.

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

Puede ser el código del servidor que causó el problema, y ​​podría no serlo. Si tiene acceso al código del servidor, puede poner algo de depuración para indicarle cuándo se cierran las conexiones de los clientes. Eso podría darle alguna indicación de cuándo y por qué las conexiones se están descartando.

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

Esto no ayudará con los 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 estaba mostrando “No se pudieron leer los datos de la conexión de transporte: el host remoto cerró forzosamente una conexión existente” e IE me decía “Encienda 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í.

Tengo ese problema en el pasado. Estoy usando PostgreSQL y cuando ejecuto mi progtwig, a veces se conecta y a 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 progtwig debe leer primero la conexión antes de hacer cualquier cosa, no sé, corregirme si me equivoco. Pero de acuerdo con mi investigación, no se trata de un problema de código, sino de la propia máquina.

Feliz Codificación!

Tengo una aplicación de terceros (Fiddler) ejecutándose para intentar ver las solicitudes que se envían. El cierre de esta aplicación me lo arregló

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

 System.Net.ServicePointManager.Expect100Continue = false; 

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

 System.Net.ServicePointManager.Expect100Continue = false; 

Este problema ocurre en algún momento debido a la razón del servidor proxy implementado en el servidor web. Para omitir el servidor proxy, ponga esta línea antes de llamar al servicio de envío.

Tuvimos un problema muy similar por el cual el sitio web de un cliente intentaba conectarse a nuestro servicio API web y obtener 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 la llamada estaba usando una versión de .Net que solo admitía TLS 1.0 y, por alguna razón, el servidor donde se ejecutaba nuestro IIS parecía haber dejado de aceptar llamadas TLS 1.0. Para diagnosticar que teníamos que habilitar explícitamente TLS 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 protocolos de seguridad antiguos no es una buena idea, la respuesta correcta en nuestro caso fue conseguir que el sitio web del cliente actualizara su código para usar TLS 1.2, pero las entradas de registro anteriores pueden ayudar a diagnosticar el problema en primer lugar.