thread - java.net.SocketException: restablecimiento de la conexión
java.net.socketexception connection reset solucion (8)
Estoy recibiendo el siguiente error al intentar leer desde un socket. Estoy haciendo un readInt()
en ese InputStream
, y estoy obteniendo este error. Al examinar la documentación, esto sugiere que la parte del cliente de la conexión cerró la conexión. En este escenario, yo soy el servidor.
Tengo acceso a los archivos de registro del cliente y no cierra 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é está sucediendo esto? ¿Qué más debo verificar? ¿Surge esto cuando hay recursos locales que quizás están llegando a los umbrales?
Me doy cuenta de que tengo la siguiente línea:
socket.setSoTimeout(10000);
justo antes de readInt()
. Hay una razón para esto (larga historia), pero solo curiosidad, ¿hay circunstancias bajo las cuales esto podría llevar al error indicado? Tengo el servidor ejecutándose en mi IDE, y dejé mi IDE atascado en un punto de interrupción, y entonces noté que los mismos errores exactos comienzan a aparecer en mis propios registros en mi IDE.
De todos modos, solo mencionarlo, espero que no sea una pista falsa. :-(
Cada vez que he tenido problemas extraños como este, generalmente me siento con una herramienta como WireShark y veo 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.
Yo tenía el mismo error. Encontré la solución para el problema ahora. El problema era que el programa del cliente estaba terminando antes de que el servidor leyera las transmisiones.
Es vergonzoso decirlo, pero cuando tuve este problema, fue simplemente un error que cerré 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 se almacenó en un búfer, antes de que lo cerrara.
En el caso de que se devolvieran cantidades de texto más largas, se lanzaba la excepción, ya que volvía más que un búfer.
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.
También tuve este problema con un programa Java que intenta enviar un comando en un servidor a través de SSH. El problema fue con la máquina ejecutando el código de Java. No tenía el 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 añadiendo la clave SSH del cliente a las claves conocidas del servidor remoto.
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 eso.
Lo más simple es cuando cierra el socket y luego escribe más datos en la secuencia de salida. Al cerrar el socket, le dijiste a tu compañero que ya terminaste de hablar, y puede olvidarse de tu conexión. Cuando envía más datos en esa secuencia de todos modos, el par lo rechaza con un RST para hacerle saber que no está escuchando.
En otros casos, un firewall que intervenga o incluso el propio host remoto podría "olvidarse" de su conexión TCP. Esto podría suceder si no envía datos por un tiempo prolongado (2 horas es un tiempo de espera común), o porque el par fue reiniciado y perdió su información sobre las conexiones activas. El envío de datos en una de estas conexiones difuntas también provocará un RST.
Actualización en respuesta a información adicional:
Observe de cerca su manejo de SocketTimeoutException
. Esta excepción se plantea si se excede el tiempo de espera configurado mientras está bloqueado en una operación de socket. El estado del zócalo en sí no cambia cuando se lanza esta excepción, pero si su manejador de excepciones cierra el zócalo y luego intenta escribir en él, estará en una condición de restablecimiento de la conexión. setSoTimeout()
está diseñado para proporcionarle una forma limpia de salir de una operación de read()
que de lo contrario podría bloquear para siempre, sin hacer cosas sucias como cerrar el socket de otro hilo.
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 lo haga, pero no es desconocido para un software comercial.
Más comúnmente, se produce al escribir en una conexión que el otro extremo ya cerró normalmente. En otras palabras, un error de protocolo de aplicación.
También puede ser causado por el cierre de un socket cuando hay datos no leídos en el búfer de recepción de socket.
En Windows, ''el software provocó la interrupción de la conexión'', que no es lo mismo que ''restablecimiento de la conexión'', es causado por el envío de problemas de red desde su extremo. Hay un artículo de la base de conocimiento de Microsoft sobre esto.
Debes inspeccionar el rastro completo con mucho cuidado,
Tengo una aplicación de socket de servidor y solucioné una java.net.SocketException: Connection reset
caso de java.net.SocketException: Connection reset
.
En mi caso sucede cuando se lee desde un objeto Socket
cliente que ha cerrado su conexión por algún motivo. (Red perdida, cortafuegos o caída de la aplicación o cierre previsto)
En realidad estaba restableciendo la conexión cuando recibí un error al leer este objeto Socket.
Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!
Lo interesante es for my JAVA Socket
si un cliente se conecta a mi ServerSocket
y cierra su conexión sin enviar nada. is.read()
llama de manera recursiva. Parece que debido a estar en un ciclo while infinito para leer desde este socket intenta leer de una conexión cerrada. Si usa algo como a continuación para la operación de lectura;
while(true)
{
Receive();
}
Luego obtienes un stackTrace algo así como sigue y sigue
java.net.SocketException: Socket is closed
at java.net.ServerSocket.accept(ServerSocket.java:494)
Lo que hice fue cerrar ServerSocket y renovar mi conexión y esperar nuevas conexiones de clientes entrantes
String Receive() throws Exception
{
try {
int readed = is.read();
....
}catch(Exception e)
{
tryReConnect();
logit(); //etc
}
//...
}
Esto restablece mi conexión para pérdidas de socket de cliente desconocidas
private void tryReConnect()
{
try
{
ServerSocket.close();
//empty my old lost connection and let it get by garbage col. immediately
clientSocket=null;
System.gc();
//Wait a new client Socket connection and address this to my local variable
clientSocket= ServerSocket.accept(); // Waiting for another Connection
System.out.println("Connection established...");
}catch (Exception e) {
String message="ReConnect not successful "+e.getMessage();
logit();//etc...
}
}
No pude encontrar otra forma porque, como puedes ver en la imagen inferior, no puedes entender si la conexión se pierde o no, sin try and catch
, porque todo parece correcto. Obtuve esta instantánea mientras recibía Connection reset
continuamente.
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 desagradables restablecimientos de conexión aparecieron en el registro del cliente y no había nada extraño en el registro del servidor. Reiniciar el cliente y 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.