Motivos oficiales del “error de conexión causado por el software: error de escritura del socket”

Dado este fragmento de seguimiento de la stack

Causado por: java.net.SocketException: El software provocó el aborto 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á arrojando esta excepción? (JVM? / Tomcat? / ¿Mi código?)
  2. ¿Qué causa esta excepción?

Respecto al # 1:

La fuente JVM de Sun no contiene este mensaje exacto, pero creo que el texto del software provocó que la conexión abortara: el error de escritura del socket proviene de la implementación nativa de SocketOutputStream :

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

Respecto al # 2

Supongo que se debe a que 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ó / finalizó / fuera de línea)

Preguntas:

  1. ¿Son correctas las suposiciones anteriores (# 1 y # 2)?
  2. ¿Puede esto diferir de la situación: “no se pudo escribir al cliente, debido a un error de red en el lado del servidor “? o ¿eso representarí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 rastreo de stack es el “error” del cliente de socket, y no hay nada que el servidor pueda haber hecho para evitarlo. (excepto que atrape la excepción, o que no utilice Sun JVM SocketOutputStream, aunque ambos no evitan realmente el hecho de que el cliente haya finalizado)

“Este error puede ocurrir cuando el sistema de red local interrumpe 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)”. Vea este artículo de MSDN . Consulte también Alguna información sobre ‘El software provocó la interrupción de la conexión’ .

Lo he visto con mayor frecuencia cuando un cortafuegos corporativo en una estación de trabajo / portátil se interpone en el camino, mata 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 (nótese la interfaz loopback 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), entonces se forma la conexión.

Sin embargo, si la máquina está conectada a un wifi público (o red doméstica), entonces el firewall interrumpe la conexión. En esta situación, conectar al cliente a la interfaz de bucle invertido funciona bien, solo que no a la interfaz doméstica / pública.

Espero que esto ayude.

Para probar qué componente falla, supervisarí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.

java.net.SocketException se lanza cuando hay un error al crear o acceder a un socket (como TCP ). Por lo general, esto puede deberse a que el servidor ha terminado la conexión (sin cerrarla correctamente), por lo tanto, antes de obtener la respuesta completa. En la mayoría de los casos, esto puede deberse al tiempo de espera (por ejemplo, la respuesta tarda demasiado o el servidor está sobrecargado con las solicitudes) o el cliente envió el SYN, pero no recibió ACK (reconocimiento de la terminación de la conexión) . Para problemas de tiempo de espera, puede considerar boost el valor de tiempo de espera.

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

Ejemplo de mensajes detallados:

  • El software provocó la interrupción de la conexión: recv failed.

    El error indica un bash de enviar el mensaje y su servidor ha abortado la conexión. Si esto sucedió al conectarse a la base de datos, esto puede estar relacionado con el uso de un controlador J / JDBC no compatible .

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

  • El software provocó la interrupción de la conexión: connect.

    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 si el servicio de escaneo de virus está bloqueando el puerto para las solicitudes de conexión salientes.

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

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

  • Restablecimiento de conexión por pares: error de escritura de socket / conexión cancelada por igual: error de escritura de socket

    La aplicación no verificó si se había agotado el tiempo de espera de la conexión keep-alive en el servidor.

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

  • Restablecimiento de la conexión por pares.

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

  • Reajuste de conexion.

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

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

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

Creo que tu pensamiento general es bueno. Esperaría una ConnectException en el escenario que no se pudo conectar. Lo anterior parece muy dirigido por el cliente.

Para cualquiera que use los progtwigs simples de Client Server y obtenga este error, se trata de un problema de flujos de Entrada o Salida no cerrados (o cerrados a principios).

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 sigue intentando escribir en ese cliente.
Así que asegúrese de que su cliente tenga su conexión abierta hasta que el servidor finalice con su salida.
Y una cosa más, no olvidó cerrar el flujo de entrada y salida.

Espero que esto ayude.
Y si aún tiene problemas, informe brevemente su problema aquí en detalles.

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

En SoapUI vaya a:

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

… y le da un gran valor, como 180000 (3 minutos), esta no será la solución perfecta para su problema porque el archivo es en realidad demasiado grande, pero al menos tendrá una respuesta.

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 de forma manual. Utilicé la bandera para habilitar múltiples conexiones a la misma base de datos (es decir, AUTO_SERVER=TRUE ), por lo que no hubo problemas para conectarse a la base de datos desde Java.

El error apareció cuando, después de un tiempo, es un largo proceso de java, decidí cerrar SQuirreL para liberar recursos. Parece que SQuirreL era el “dueño” de la instancia del servidor de base de datos 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

Mi servidor estaba lanzando 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 ayudara a alguien

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

Se le pide al servidor que autentique el certificado del cliente, pero el cliente proporciona un certificado que Extended Key Usage no admite la autenticación del cliente, por lo que el servidor no acepta el certificado del cliente y luego cierra la conexión.

Estaba enfrentando el mismo problema con wireMock mientras me burlaba de las llamadas API restantes. Antes 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);