Recibo el siguiente error al intentar leer desde un socket. Estoy haciendo algo readInt()
al respecto InputStream
y obtengo este error. Al leer la documentación, esto sugiere que la parte del cliente de la conexión la cerró. En este escenario, yo soy el servidor.
Tengo acceso a los archivos de registro del cliente y no está cerrando la conexión, y de hecho sus archivos de registro sugieren que estoy cerrando la conexión. Entonces, ¿alguien tiene una idea de por qué sucede esto? ¿Qué más verificar? ¿Esto surge cuando hay recursos locales que tal vez están alcanzando umbrales?
Tengo en cuenta que tengo la siguiente línea:
socket.setSoTimeout(10000);
justo antes de la readInt()
. Hay una razón para esto (larga historia), pero solo curiosidad, ¿hay circunstancias bajo las cuales esto podría conducir al error indicado? Tengo el servidor ejecutándose en mi IDE, y por casualidad dejé mi IDE atascado en un punto de interrupción, y luego noté que exactamente los mismos errores comienzan a aparecer en mis propios registros en mi IDE.
De todos modos, solo mencionándolo, espero que no sea un arenque rojo. :-(
fuente
Respuestas:
Hay varias causas posibles.
El otro extremo ha restablecido deliberadamente la conexión, de una manera que no documentaré aquí. Es raro, y generalmente incorrecto, que el software de aplicación haga esto, pero no es desconocido para el software comercial.
Más comúnmente, es causado al escribir en una conexión que el otro extremo ya se ha cerrado normalmente. En otras palabras, un error de protocolo de aplicación.
También puede ser causado al cerrar un socket cuando hay datos no leídos en el buffer de recepción del socket.
En Windows, "el software causó la cancelación de la conexión", que no es lo mismo que el "restablecimiento de la conexión", es causado por problemas de red que se envían desde su extremo. Hay un artículo de Microsoft Knowledge Base sobre esto.
fuente
El restablecimiento de la conexión simplemente significa que se recibió un TCP RST. Esto sucede cuando su compañero recibe datos que no puede procesar, y puede haber varias razones para ello.
Lo más simple es cuando cierra el socket y luego escribe más datos en la secuencia de salida. Al cerrar el zócalo, le dijiste a tu compañero que habías terminado de hablar, y puede olvidarse de tu conexión. Cuando envía más datos en ese flujo de todos modos, el igual lo rechaza con un RST para hacerle saber que no está escuchando.
En otros casos, un cortafuegos intermedio o incluso el host remoto en sí podría "olvidarse" de su conexión TCP. Esto podría suceder si no envía ningún dato durante mucho tiempo (2 horas es un tiempo de espera común) o porque el par se reinició y perdió su información sobre las conexiones activas. El envío de datos en una de estas conexiones inactivas también causará un RST.
Actualización en respuesta a información adicional:
Eche un vistazo de cerca a su manejo de
SocketTimeoutException
. Esta excepción se genera si se excede el tiempo de espera configurado mientras está bloqueado en una operación de socket. El estado del socket en sí no cambia cuando se lanza esta excepción, pero si su controlador de excepción cierra el socket y luego intenta escribir en él, estará en una condición de restablecimiento de conexión.setSoTimeout()
está destinado a darle una manera limpia de salir de unaread()
operación que de otra manera podría bloquearse para siempre, sin hacer cosas sucias como cerrar el socket de otro hilo.fuente
Cada vez que he tenido problemas extraños como este, generalmente me siento con una herramienta como WireShark y miro los datos sin procesar que se pasan de un lado a otro. Es posible que se sorprenda de dónde se desconectan las cosas y solo se le notificará cuando intente leer.
fuente
Es vergonzoso decirlo, pero cuando tuve este problema, fue simplemente un error que estaba cerrando la conexión antes de leer todos los datos. En los casos en que se devolvieron pequeñas cadenas, funcionó, pero eso probablemente se debió a que toda la respuesta estaba almacenada antes de cerrarla.
En caso de que se devuelva una cantidad mayor de texto, se produjo la excepción, ya que más de un búfer regresaba.
Puede verificar este descuido. Recuerde que abrir una URL es como un archivo, asegúrese de cerrarla (liberar la conexión) una vez que se haya leído por completo.
fuente
Debes inspeccionar el rastro completo con mucho cuidado,
Tengo una aplicación de socket de servidor y arreglé un
java.net.SocketException: Connection reset
caso.En mi caso, sucede mientras leo de un cliente
Socket
objeto que está cerrado su conexión por alguna razón. (Red perdida, cortafuegos o aplicación bloqueada o cierre previsto)En realidad, estaba restableciendo la conexión cuando recibí un error al leer este objeto Socket.
Lo interesante es que
for my JAVA Socket
si un cliente se conecta a miServerSocket
y cierra su conexión sin enviar nada seis.read()
llama recursivamente. Parece que debido a que está en un bucle while infinito para leer desde este socket, intenta leer desde una conexión cerrada. Si usa algo como el siguiente para la operación de lectura;Luego obtienes un stackTrace algo como abajo una y otra vez
Lo que hice fue cerrar ServerSocket y renovar mi conexión y esperar más conexiones entrantes de clientes
Esto restablece mi conexión por pérdidas de socket de cliente desconocido
No pude encontrar otra manera porque, como puede ver en la imagen de abajo, no puede entender si la conexión se pierde o no sin una
try and catch
, porque todo parece estar bien. Obtuve esta instantánea mientras recibíaConnection reset
continuamente.fuente
Yo tenía el mismo error. Encontré la solución para el problema ahora. El problema era que el programa cliente estaba terminando antes de que el servidor leyera las transmisiones.
fuente
Tuve este problema con un sistema SOA escrito en Java. Estaba ejecutando tanto el cliente como el servidor en diferentes máquinas físicas y funcionaron bien durante mucho tiempo, luego esos reajustes de conexión desagradables aparecieron en el registro del cliente y no había nada extraño en el registro del servidor. Reiniciar tanto el cliente como el servidor no resolvió el problema. Finalmente descubrimos que el montón en el lado del servidor estaba bastante lleno, así que aumentamos la memoria disponible para la JVM: ¡problema resuelto! Tenga en cuenta que no había OutOfMemoryError en el registro: la memoria era escasa, no estaba agotada.
fuente
Verifique la versión de Java de su servidor. Me sucedió porque mi Weblogic 10.3.6 estaba en JDK 1.7.0_75 que estaba en TLSv1. El punto final de descanso que intentaba consumir era cerrar cualquier cosa por debajo de TLSv1.2.
Por defecto, Weblogic intentaba negociar el protocolo compartido más fuerte. Consulte los detalles aquí: Problemas con la configuración de la propiedad del sistema https.protocols para conexiones HTTPS .
Agregué un registro SSL detallado para identificar el TLS compatible. Esto indicaba que TLSv1 se estaba utilizando para el apretón de manos.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack
Resolví esto enviando la función a nuestro producto compatible con JDK8, JDK8 por defecto es TLSv1.2. Para aquellos restringidos a JDK7, también probé con éxito una solución alternativa para Java 7 al actualizar a TLSv1.2. Usé esta respuesta: Cómo habilitar TLS 1.2 en Java 7
fuente
También tuve este problema con un programa Java que intentaba enviar un comando en un servidor a través de SSH. El problema fue con la máquina ejecutando el código Java. No tenía permiso para conectarse al servidor remoto. El método write () funcionaba bien, pero el método read () arrojaba java.net.SocketException: restablecimiento de la conexión. Solucioné este problema al agregar la clave SSH del cliente a las claves conocidas del servidor remoto.
fuente
En mi experiencia, a menudo encuentro las siguientes situaciones;
Si trabaja en una empresa corporativa, comuníquese con el equipo de redes y seguridad. Porque en las solicitudes realizadas a servicios externos, puede ser necesario dar permiso para el punto final relevante.
Otro problema es que el certificado SSL puede haber expirado en el servidor donde se ejecuta su aplicación.
fuente