¿Hay una fuga en el descriptor de archivos cuando se usan sockets en una plataforma Linux?

StackOverflow https://stackoverflow.com/questions/429762

Pregunta

Si abro y cierro un socket llamando por ejemplo

Socket s = new Socket( ... );
s.setReuseAddress(true);
in = s.getInputStream();
...
in.close(); 
s.close();      

Linux declara que este socket todavía está abierto o al menos el descriptor de archivo para la conexión está presente. Al consultar los archivos abiertos para este proceso por lsof, hay una entrada para la conexión cerrada:

COMMAND  PID   USER   FD   TYPE DEVICE     SIZE   NODE NAME
java    9268 user    5u  sock    0,4           93417 can't identify protocol

Esta entrada permanece hasta que se cierra el programa. ¿Hay alguna otra forma de cerrar finalmente el zócalo? Estoy un poco preocupado de que mi aplicación Java pueda bloquear muchos descriptores de archivos. es posible? ¿O Java conserva estos sockets para reutilizarlos incluso si ReuseAdress está configurado?

¿Fue útil?

Solución

Si esos sockets están en el estado TIME_WAIT, esto es normal, al menos por un tiempo. Verifique eso con netstat; Es común que los zócalos permanezcan unos minutos para asegurarse de que los datos rezagados del zócalo se descarten correctamente antes de reutilizar el puerto para un nuevo zócalo.

Otros consejos

También es posible que desee comprobar /proc/<pid>/fd, el directorio contendrá todos los descriptores de archivo abiertos actualmente. Si un archivo desaparece después de cerrar el socket, no se encontrará con ningún problema (al menos no con los descriptores de sus archivos :).

Creo que no es el problema de su programa.

En SUN_Java, cuando se carga la biblioteca nativa relacionada con el socket, se creará un MAGIC_SOCK fd.

escribir en MAGIC_SOCK dará como resultado una excepción de descanso de conexión, y leer en MAGIC_SOCK dará como resultado un EOF.

el par del magic_sock se ha cerrado por completo, y el magic_sock en sí está medio cerrado, y el estado permanecerá & "; no se puede identificar el protocolo &";

Tal vez es un socket de algún otro protocolo (" No se puede identificar el protocolo " eh?) utilizado internamente en la implementación para hacer algo, que se crea en el primer socket.

¿Ha intentado crear y cerrar sockets repetidamente para ver si estos sockets realmente persisten? Parece probable que esto sea único.

Java probablemente usa sockets internamente para muchas cosas: pueden ser Unix, Netlink (bajo Linux) o algún otro tipo de socket.

Cree un pequeño script bash para monitorear los sockets abiertos para una determinada aplicación o pid, y déjelo ejecutar mientras prueba su aplicación java.

De todos modos, dudo que haya algún tipo de fugas en esto, ya que los zócalos son muy utilizados en el mundo de Linux / Unix y este tipo de problema surgiría muy rápidamente

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top