Razones oficiales de "El software causó la cancelación de la conexión: error de escritura del socket"


157

Dado este fragmento de seguimiento de pila

Causado por: java.net.SocketException: el software provocó la cancelación de la conexión: error de escritura del socket
 en java.net.SocketOutputStream.socketWrite0 (Método nativo)

Traté de responder las siguientes preguntas:

  1. ¿Qué código está lanzando esta excepción? (JVM? / Tomcat? / Mi código?)
  2. ¿Qué causa que se arroje esta excepción?

Con respecto al n. ° 1:

La fuente JVM de Sun no contiene este mensaje exacto, pero creo que el texto Software causó la cancelación de la conexión: el error de escritura del socket es de la implementación nativa de SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

Con respecto al n. ° 2

Mi conjetura es que se produce cuando el cliente ha terminado la conexión, antes de obtener la respuesta completa (por ejemplo, envió una solicitud, pero antes de obtener la respuesta completa, se cerró / terminó / desconectado)

Preguntas:

  1. ¿Son correctos los supuestos anteriores (# 1 y # 2)?
  2. ¿Se puede diferenciar esto de la situación: "no se pudo escribir al cliente debido a un error de red en el lado del servidor "? ¿O eso generaría el mismo mensaje de error?
  3. Y lo más importante: ¿hay un documento oficial (por ejemplo, de Sun) que indique lo anterior?

Necesito tener una prueba de que este seguimiento de la pila es el "error" del cliente de socket, y no hay nada que el servidor podría haber hecho para evitarlo. (excepto detectar la excepción o usar un SocketOutputStream que no sea Sun JVM, aunque ambos realmente no evitan el hecho de que el cliente haya finalizado)


Tengo este problema al cancelar una descarga con Firefox
koppor

Eran Hey yo también estoy recibiendo esta excepción al enviar / escritura ( outs.write(audioBytes);) byte[]a OutputStream. Cuando el audio se reproduce y se reproduce, si el usuario hace clic en cualquier otro menú (que envía una solicitud del servidor), recibí el mismo error en la consola. Entonces, ¿es seguro ignorar esta excepción?
Amogh

1
@Amogh - Parece que sí, sí. Básicamente, según lo que describen las respuestas, se trata de un error específico de Windows, pero supongo que en Linux obtendrá la misma excepción solo con una redacción diferente ... a través de un enchufe a una ubicación remota X y X se desconectaron en el medio, pero estoy seguro de que no es la forma más precisa de describirlo)
Eran Medan

1
Para mí, esto sucedió cuando el servidor de la base de datos se reinició y la aplicación aún intentaba consultar utilizando conexiones abiertas anteriormente. No estoy seguro de por qué no se actualizaron, ya que estamos utilizando la agrupación basada en DBCP. Pero reiniciar la aplicación solucionó el problema.
Kshitiz Sharma

Respuestas:


55

Este error puede ocurrir cuando el sistema de red local cancela una conexión, como cuando WinSock cierra una conexión establecida después de que falla la retransmisión de datos (el receptor nunca reconoce los datos enviados en un socket de flujo de datos).

Ver este artículo de MSDN . Consulte también cierta información sobre 'El software causó la cancelación de la conexión' .



3
@MatGessel Ese artículo simplemente repite la confusión y agrega algo propio. WSAECONNABORTED es un código de error de Winsock, por lo que no puede haber una explicación de Berkeley para ello. La situación descrita sobre el servidor HTTP produciría ECONNRESET, no WSAECONNABORTED.
Marqués de Lorne

@EJP, también recibo esta excepción al enviar / escribir (outs.write (audioBytes);) byte [] en OutputStream. Cuando el audio se está reproduciendo y durante la reproducción, si el usuario hace clic en cualquier otro menú (que envía una solicitud del servidor), recibí el mismo error en la consola. Entonces, ¿es seguro ignorar esta excepción?
Amogh

1
@rustyx Las tres fuentes citadas aquí afirman que se produce por fallas de ACK. Si tiene una fuente para su propio reclamo, cítelo.
Marqués de Lorne

2
Esta no es una respuesta real, ya que no le brinda información para continuar con el problema. La respuesta aquí es básicamente "algo malo sucedió en la red". Sería realmente útil comprender qué registros adicionales y otros registros de actividad podrían permitirme identificar el problema subyacente.
Derek Bennett

11

Se java.net.SocketExceptionproduce cuando hay un error al crear o acceder a un socket (como TCP ). Esto generalmente puede ser causado cuando el servidor ha terminado la conexión (sin cerrarla correctamente), antes de obtener la respuesta completa. En la mayoría de los casos, esto puede deberse al problema del tiempo de espera (p. Ej., La respuesta toma demasiado tiempo o el servidor está sobrecargado con las solicitudes), o el cliente envió el SYN, pero no recibió ACK (reconocimiento de la finalización de la conexión) . Para problemas de tiempo de espera, puede considerar aumentar el valor del tiempo de espera.

La excepción de socket generalmente viene con el mensaje de detalle especificado sobre el problema.

Ejemplo de mensajes detallados:

  • El software provocó la cancelación de la conexión: la recv falló.

    El error indica un intento de enviar el mensaje y su servidor ha interrumpido la conexión. Si esto sucedió mientras se conectaba a la base de datos, esto puede estar relacionado con el uso controlador JDBC Connector / J no compatible .

    Posible solución: asegúrese de tener bibliotecas / controladores adecuados en su CLASSPATH.

  • El software provocó la cancelación de la conexión: conectar.

    Esto puede suceder cuando hay un problema para conectarse al control remoto. Por ejemplo, debido a que el verificador de virus rechaza las solicitudes de correo remoto .

    Posible solución: compruebe el servicio de detección de virus si está bloqueando el puerto para las solicitudes salientes de conexiones.

  • El software provocó la cancelación de la conexión: error de escritura del socket.

    Posible solución: asegúrese de escribir la longitud correcta de bytes en la secuencia. Así que revisa lo que estás enviando. Ver este hilo .

  • Conexión restablecida por igual: error de escritura de socket / Conexión cancelada por igual: error de escritura de socket

    La aplicación no verificó si la conexión de mantenimiento se había agotado en el lado del servidor.

    Posible solución: asegúrese de que el HttpClient no sea nulo antes de leer desde la conexión. E13222_01

  • Conexión restablecida por un par.

    La conexión ha sido terminada por el par (servidor).

  • Reajuste de conexion.

    La conexión ha sido finalizada por el cliente o cerrada por el servidor al final de la conexión debido a la solicitud con la solicitud.

    Consulte: ¿Qué está causando mi java.net.SocketException: restablecimiento de la conexión?


Solo uno de estos 6 puntos responde realmente la pregunta, incorrectamente. Varios otros son incorrectos también. La aplicación no puede 'verificar si la conexión de mantenimiento se ha agotado en el lado del servidor'. El HttpClientser nullno puede causar a SocketException. No escribir la longitud correcta en la secuencia tampoco.
Marqués de Lorne

9

Lo he visto con mayor frecuencia cuando un firewall corporativo en una estación de trabajo / computadora portátil se interpone, interrumpe la conexión.

p.ej. Tengo un proceso de servidor y un proceso de cliente en la misma máquina. El servidor está escuchando en todas las interfaces (0.0.0.0) y el cliente intenta una conexión a la interfaz pública / doméstica (tenga en cuenta no la interfaz de bucle invertido 127.0.0.1).

Si la máquina tiene su red desconectada (por ejemplo, wifi apagado), entonces se forma la conexión. Si la máquina está conectada a la red corporativa (directamente o vpn), se forma la conexión.

Sin embargo, si la máquina está conectada a un wifi público (o red doméstica), el cortafuegos interrumpe la conexión. En esta situación, la conexión del cliente a la interfaz de bucle de retorno funciona bien, pero no a la interfaz de inicio / pública.

Espero que esto ayude.


3
Los cortafuegos evitan las conexiones. La pregunta es sobre restablecer una conexión existente.
Marqués de Lorne

4

Para probar qué componente falla, monitorearía la comunicación TCP / IP utilizando wireshark y vería quién está cerrando el puerto, también los tiempos de espera podrían ser relevantes.


Nadie está cerrando el puerto. El sistema operativo está abortando la conexión.
Marqués de Lorne

@EJP He visto que esto sucede cuando se sobrecarga y se queda sin memoria. No estoy seguro de que sea el sistema operativo el que cierre la conexión, pero JVM se vuelve loco.
Zee

1
@Zee Hay una diferencia entre cerrar un puerto, que es visible como FIN en Wireshark, y abortar la conexión, que no lo es.
Marqués de Lorne

2

¿Ha verificado el código fuente de Tomcat y la fuente JVM? Eso puede darte más ayuda.

Creo que tu pensamiento general es bueno. Esperaría un ConnectExceptionen el escenario que no podría conectarse. Lo anterior parece muy impulsado por el cliente.


3
Sí, lo he comprobado. Las fuentes de Tomcat no contenían ninguna permutación de la oración, gracias.
Eran Medan

1
No, no ha verificado la fuente Tomcat Y la fuente JVM.
Stephen C

O si ha verificado la fuente JVM, no ha verificado toda.
Stephen C

1
@Ehrann: es probable que la cadena del mensaje esté en las fuentes nativas. Pero también debe verificar el registro de eventos. En mi opinión, es probable que este último sea más informativo.
Stephen C

66
Esta cadena de mensaje proviene del sistema operativo en realidad.
Marqués de Lorne

2

Para cualquiera que use programas simples de Servidor de cliente y obtenga este error, es un problema de flujos de entrada o salida no cerrados (o cerrados a principios).


2
No, no lo es. Eso constituiría una fuga de enchufe, lo que eventualmente causaría un agotamiento de FD.
Marqués de Lorne

0

Estaba enfrentando el mismo problema.
Comúnmente, este tipo de error ocurre debido a que el cliente ha cerrado su conexión y el servidor aún intenta escribir en ese cliente.
Así que asegúrese de que su cliente tenga su conexión abierta hasta que el servidor haya terminado con su flujo de salida.
Y una cosa más, no se olvide de cerrar el flujo de entrada y salida.

Espero que esto ayude.
Y si aún enfrenta un problema, breve su problema aquí en detalles.


3
@BhavinChhatrola No, una respuesta incorrecta. La situación descrita produce 'restablecimiento de la conexión por igual', no el error en la pregunta.
Marqués de Lorne

0

Este error me ocurrió mientras probaba mi servicio de jabón con el cliente SoapUI, básicamente estaba tratando de recibir un mensaje muy grande (> 500kb) y SoapUI cerró la conexión por tiempo de espera.

En SoapUI ve a:

Archivo -> Preferencias - Tiempo de espera de socket (ms)

... y poner un valor grande, como 180000 (3 minutos), esta no será la solución perfecta para su problema porque el archivo es de hecho demasiado grande, pero al menos tendrá una respuesta.


0

Conexión cerrada en otro cliente.

En mi caso, el error fue:

java.net.SocketException: Software caused connection abort: recv failed

Se recibió en eclipse mientras se depuraba una aplicación Java que accedía a una base de datos H2. El origen del error fue que inicialmente había abierto la base de datos con SQuirreL para verificar la integridad manualmente. Utilicé el indicador para habilitar múltiples conexiones a la misma base de datos (es decir AUTO_SERVER=TRUE), por lo que no hubo ningún problema para conectarme a la base de datos desde Java.

El error apareció cuando, después de un tiempo, es un proceso largo de Java, decidí cerrar SQuirreL para liberar recursos. Parece que SQuirreL fue el "propietario" de la instancia del servidor DB y que se cerró con la conexión SQuirreL.

Reiniciar la aplicación Java no produjo el error nuevamente.

config

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

0

En mi caso, desarrollé el lado del cliente y del servidor, y tengo la excepción:

Causa: error al ordenar argumentos; La excepción anidada es: java.net.SocketException: el software causó la cancelación de la conexión: error de escritura del socket

cuando las clases en cliente y servidor son diferentes. No descargo las clases del servidor (Interfaces) en el cliente, solo agrego los mismos archivos en el proyecto. Pero el camino debe ser exactamente el mismo. Por ejemplo, en el proyecto del servidor tengo paquetes java \ rmi \ services con alguna interfaz de servicio e implementaciones, tengo que crear el mismo paquete en el proyecto del cliente. Si lo cambio por java / rmi / server / services, por ejemplo, obtengo la excepción anterior. La misma excepción si la versión de la interfaz es diferente entre el cliente y el servidor (incluso con una fila vacía agregada inadvertidamente ... Creo que rmi hace una especie de hash de clases para verificar la versión ... No sé ... Si pudiera ayuda ...


-1

Mi servidor lanzó esta excepción en el pase 2 días y lo resolví moviendo la función de desconexión con:

outputStream.close();
inputStream.close();
Client.close();

Hasta el final del hilo de listado. si ayudará a alguien


-1

En la situación que se explica a continuación, el lado del cliente arrojará dicha excepción:

Se le pide al servidor que autentique el certificado del cliente, pero el cliente proporciona un certificado cuyo Uso de clave extendida no admite la autenticación del cliente, por lo que el servidor no acepta el certificado del cliente y luego cierra la conexión.


Esta respuesta es incorrecta. En el caso de que describa, se lanzará una excepción SSLE.
Presidente James K. Polk

en realidad arrojó SocketException al igual que la pregunta actual, que había probado
xiaoming

-1

El lado del cliente SSL arrojará dicha excepción en la siguiente situación (Lo había probado),:

se le pide al servidor que autentique el certificado del cliente, pero el cliente proporciona un certificado que el uso de clave extendida no admite la autenticación del cliente.


-3

Estaba enfrentando el mismo problema con wireMock mientras me burlaba de las llamadas API restantes. Anteriormente estaba definiendo el servidor de esta manera:

WireMockServer wireMockServer = null;

Pero debe definirse como se muestra a continuación:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

Eso causaría un NullPointerException, no este problema.
Marqués de Lorne
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.