Una conexión existente fue cerrada por la fuerza por el host remoto

159

Estoy trabajando con una aplicación comercial que arroja una SocketException con el mensaje,

Una conexión existente fue cerrada por la fuerza por el host remoto

Esto sucede con una conexión de socket entre el cliente y el servidor. La conexión está viva y bien, y se están transfiriendo montones de datos, pero luego se desconecta de la nada.

Alguien ha visto esto antes? ¿Cuáles podrían ser las causas? Puedo adivinar algunas causas, pero ¿hay alguna manera de agregar más a este código para determinar cuál podría ser la causa?

Cualquier comentario / ideas son bienvenidas.

... Lo último ...

Tengo algunos registros de un seguimiento de .NET,

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

Basado en otras partes del registro, he visto el hecho de que dice '0 # 0' significa que se está enviando un paquete de 0 bytes de longitud. Pero, ¿qué significa esto realmente?

Está ocurriendo una de dos posibilidades, y no estoy seguro de cuál,

1) La conexión se está cerrando, pero los datos se están escribiendo en el socket, creando así la excepción anterior. El 0 # 0 simplemente significa que no se envió nada porque el socket ya estaba cerrado.

2) La conexión aún está abierta y se está enviando un paquete de cero bytes (es decir, el código tiene un error) y el 0 # 0 significa que se está intentando enviar un paquete de cero bytes.

¿Que cuentas? Supongo que podría no ser concluyente, pero ¿tal vez alguien más ha visto este tipo de cosas?

Peter
fuente
Solo una actualización. Parece que wireshark no lo va a cortar en este caso debido a la configuración de nuestra red. Pero espero poder probar esto, blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx que está rastreando usando .NET que debería producir algunos archivos de registro. Los mantendré informados ...
Peter
1
también se sabe que

Respuestas:

98

Esto generalmente significa que el lado remoto cerró la conexión (generalmente enviando un RSTpaquete TCP / IP ). Si está trabajando con una aplicación de terceros, las causas probables son:

  • Está enviando datos con formato incorrecto a la aplicación (que podría incluir el envío de una solicitud HTTPS a un servidor HTTP)
  • El enlace de red entre el cliente y el servidor se cae por algún motivo
  • Ha desencadenado un error en la aplicación de terceros que hizo que se bloqueara
  • La aplicación de terceros ha agotado los recursos del sistema

Es probable que el primer caso sea lo que está sucediendo.

Puede encender Wireshark para ver exactamente lo que está sucediendo en el cable para reducir el problema.

Sin información más específica, es poco probable que alguien aquí realmente pueda ayudarlo mucho.

RarrRarrRarr
fuente
2
Excelente. Gracias. La otra cosa sobre wireshark. Recopila tantos datos, ¿cómo podría filtrar algo como esto? Si Wireshark muestra hasta algo que podría publicar aquí más adelante ...
Peter
44
Debería poder filtrar el volcado de Wireshark por dirección IP y número de puerto, al menos. Después de eso, probablemente sea más útil mirar el final de la transmisión (donde algo salió mal) y trabajar hacia atrás hasta que pueda detectar dónde se estropearon las cosas por primera vez. Dependiendo de la complejidad del protocolo involucrado, puede ser realmente fácil o casi imposible ...
RarrRarrRarr
44
¿Hay una fuente para los elementos con viñetas, o la respuesta del jugador a continuación simplemente copió su lista?
Zack
77
Tenga en cuenta que "enviar datos con formato incorrecto" podría significar enviar una httpssolicitud a un httpservidor y probablemente al revés.
AXMIM
2
En mi caso, recibía esta excepción solo cuando llamaba a una API cuando ejecutaba la aplicación localmente. No hay problemas en entornos de desarrollo, qa o prod. ¿La solución? Usando http en lugar de https localmente. Creemos que puede estar relacionado con un equilibrador de carga. Pero acabamos de actualizar nuestro dev, qa y prod web.configs con transformaciones para https. Problema resuelto.
Kershaw
82

El uso de TLS 1.2 resolvió este error.
Puede forzar su aplicación usando TLS 1.2 con esto (asegúrese de ejecutarla antes de llamar a su servicio):

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 

Otra solución:
habilite la criptografía sólida en su máquina o servidor local para usar TLS1.2 porque de forma predeterminada está deshabilitada, por lo que solo se usa TLS1.0.
Para habilitar una criptografía sólida, ejecute estos comandos en PowerShell con privilegios de administrador:

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 

Debe reiniciar su computadora para que estos cambios surtan efecto.

willmaz
fuente
1
Puede agregar varios valores juntos para admitir múltiples protocolos. Entonces, para admitir todo, desde SSL3 a TLS1.2, configure SecurityProtocol = (SecurityProtocolType) 4080.
Abacus
29

Esto no es un error en su código. Proviene de la implementación de Socket de .Net. Si utiliza la implementación sobrecargada de EndReceive como se muestra a continuación, no obtendrá esta excepción.

    SocketError errorCode;
    int nBytesRec = socket.EndReceive(ar, out errorCode);
    if (errorCode != SocketError.Success)
    {
        nBytesRec = 0;
    }
cagatay
fuente
1
Esto viene del sistema operativo y, en última instancia, del par. Se requiere una explicación adicional de la alegación de que es un error de software.
Marqués de Lorne
55
+1. En mi programa C #, estaba golpeando mi cabeza en cuanto a por qué EndReceiveestá lanzando una excepción cuando hay una terminación de cliente elegante. No sabía que esto es por diseño. Siento que su mal diseño arroja una excepción en los flujos de código normales. Gracias a Dios por el método sobrecargado.
Pavan Manjunath
2
@MSaudi Esto está utilizando una llamada asincrónica, asegúrese de comprender que su código no se detendrá mientras procesa los datos que se devuelven. El ejemplo usa msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx . Básicamente, debe tener una StateObjectclase con public byte[] buffer = new byte[1024], public Socket socket;y llamar a una función llamada Receive(Socket s), que lo hace StateObject so = new StateObject(); so.socket = s; s.BeginReceive(so.buffer, 0, 256, 0, new AsyncCallback(ReceiveCallback), so); y en void ReceiveCallback(IAsyncResult ar)ese código, arriba.
vapcguy
2
@cagatay Si bien ofrece una solución, nunca vi valor en los métodos asincrónicos en los que necesita saber de inmediato qué regresa después de hacer lo suyo Sendantes de poder hacer cualquier otra cosa.
vapcguy
3
En realidad, descubrí que este método no es infalible. También puede causar el error del OP: stackoverflow.com/questions/17790612/…
vapcguy
10

Solución simple para este problema molesto común:

Simplemente vaya a su archivo " .context.cs" (ubicado debajo de " .context.tt" que se encuentra debajo de su archivo "* .edmx").

Luego, agregue esta línea a su constructor:

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

Espero que esto sea útil.

ayheber
fuente
@Esi donde poner esto? y sin tipo de retorno?
Khalil Khalaf
2
@ FirstStep: Porque este es un constructor.
Nikhil Agrawal
3
Esto solo ayuda a aquellos que usan Entity Framework que están experimentando el problema, no aquellos que están haciendo una socket.Send(x); byte[] buffer = new byte[1]; socket.Receive(buffer, 0, 1, 0);lectura simple de los bytes devueltos, que fue el problema del OP.
vapcguy
si usar ENTITY FRAMEWORKsolo esta solución funciona !!! solo esto ! gracias hermano :)
Rao Hammas
9

Tenía el mismo error. Realmente funcionó en caso de que el tráfico fuera enviado usando algún proxy (violinista en mi caso) .NET Framework actualizado de 4.5.2 a> = 4.6 y ahora todo funciona bien. La solicitud real fue:
new WebClient().DownloadData("URL");
La excepción fue:

SocketException: el host remoto cerró a la fuerza una conexión existente

0x49D1
fuente
55
Esta fue una forma de resolver las cosas por mí. En realidad, estaba relacionado con la versión de TLS .NET utilizada de forma predeterminada. 4.5.2 y versiones anteriores utilizan TLS 1.0, mientras que 4.6 y versiones posteriores son más inteligentes al permitir 1.1 y 1.2. Esto también fue demostrable al reducir el requisito de TLS en el servidor a 1.0, lo que también solucionó el problema.
HotN
4

Tengo esta excepción debido a la referencia circular en la entidad. En la entidad que se parece

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

Agregué [IgnoreDataMemberAttribute] a la propiedad Parent. Y eso resolvió el problema.

Bazaleev Nikolay
fuente
2

Si se ejecuta en un servicio .Net 4.5.2

Para mí, el problema se agravó porque la llamada se estaba ejecutando en un servicio .Net 4.5.2. Seguí la sugerencia de @willmaz pero recibí un nuevo error.

Al ejecutar el servicio con el registro activado, vi que el apretón de manos con el sitio de destino iniciaría correctamente (y enviaría el token del portador) pero en el siguiente paso para procesar la llamada de publicación, parecería que se cae el token de autenticación y el sitio responde con Unauthorized.

Resultó que las credenciales del grupo de servicio no tenían derechos para cambiar TLS (?) Y cuando puse mi cuenta de administrador local en el grupo, todo funcionó.

ΩmegaMan
fuente
2

Para cualquiera que obtenga esta excepción mientras lee datos de la transmisión, esto puede ayudar. Estaba recibiendo esta excepción cuando leía el HttpResponseMessage en un bucle como este:

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

Después de un tiempo descubrí que el culpable era el tamaño del búfer, que era demasiado pequeño y no funcionaba bien con mi débil instancia de Azure. Lo que ayudó fue cambiar el código a:

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

El método CopyTo () tiene un tamaño de búfer predeterminado de 81920. El búfer más grande aceleró el proceso y los errores se detuvieron de inmediato, probablemente debido a que aumentaron las velocidades generales de descarga. Pero, ¿por qué la velocidad de descarga es importante para evitar este error?

Es posible que se desconecte del servidor porque las velocidades de descarga caen por debajo del umbral mínimo que el servidor está configurado para permitir. Por ejemplo, en caso de que la aplicación desde la que está descargando el archivo esté alojada en IIS, puede ser un problema con la configuración de http.sys:

"Http.sys es la pila de protocolos http que IIS utiliza para realizar la comunicación http con los clientes. Tiene un temporizador llamado MinBytesPerSecond que es responsable de eliminar una conexión si su velocidad de transferencia cae por debajo de un umbral de kb / seg. De manera predeterminada, ese umbral es establecido en 240 kb / seg. "

El problema se describe en este viejo blog del equipo de desarrollo de TFS y concierne específicamente a IIS, pero puede indicarle una dirección correcta. También menciona un error antiguo relacionado con este atributo http.sys: enlace

En caso de que use los servicios de aplicaciones de Azure y el aumento del tamaño del búfer no elimine el problema, intente escalar su máquina también. Se le asignarán más recursos, incluido el ancho de banda de conexión.

Andrej Lucansky
fuente
0

Tuve el mismo problema y logré resolverlo eventualmente. En mi caso, el puerto al que el cliente envía la solicitud no tenía un certificado SSL vinculante. Así que solucioné el problema vinculando un certificado SSL al puerto en el lado del servidor. Una vez hecho eso, esta excepción desapareció.

iefgnoix
fuente
-1

Este error ocurrió en mi aplicación con el protocolo CIP cuando no envié o recibí datos en menos de 10 segundos.

Esto fue causado por el uso del método abierto hacia adelante. Puede evitar esto trabajando con otro método o instalando una tasa de actualización de menos de 10 segundos que mantenga su conexión abierta hacia adelante.

Belekz
fuente