Trouver ce que les sockets réseau sont ouverts dans le courant de la machine virtuelle Java
Je suis en train d'écrire un bout-à-bout d'essai que mon programme Java libère de toutes ses ressources - fils, serveur de sockets sockets client. C'est une bibliothèque, afin de libérer des ressources en sortant de la JVM n'est pas une option. Test de la libération de threads était facile, parce que vous pouvez demander à un ThreadGroup pour tous les threads, mais je n'ai pas encore trouvé un bon moyen d'obtenir une liste de tous les sockets réseau, que le courant de la JVM utilise.
Est-il un moyen d'obtenir à partir d'une JVM la liste de tous les clients et le serveur de sockets, similaire à la commande netstat? Je suis en utilisant Netty avec OIO (c'est à dire java.net.ServerSocket et java.net.Socket) sur l'île de Java 7. La solution doit travailler à la fois sur Windows et Linux.
Mon premier choix serait de demander, à partir de la JVM à l'aide de Java pur. J'ai essayé de regarder pour un MX de Haricots ou similaire, mais n'en trouvent pas.
Une autre option pourrait être de se connecter à la JVM de profilage/débogage Api et de demander toutes les instances de Socket et ServerSocket, mais je ne sais pas comment faire et si elle peut être effectuée sans code natif (autant que je sache, JVMTI est natif uniquement). Aussi, il ne faut pas faire les tests lent (même mon plus lent bout-à-bout d'essai est seulement de 0,5 secondes, ce qui inclut le démarrage d'un autre processus de JVM).
S'interrogeant sur la JVM ne fonctionne pas, une troisième option serait de créer un design qui suit toutes les prises qu'ils sont créés. Cela a le désavantage d'avoir une possibilité de manquer un endroit où les sockets sont créés. Depuis que je suis en utilisant Netty, il semble que mis en œuvre par emballage ChannelFactory et à l'aide d'un ChannelGroup.
- Je voudrais exécuter la commande netstat à partir de Java ou de numérisation
/proc/self/fd
pour les sockets 😉 - Il faut travailler à la fois sur Windows et Linux, donc netstat n'est pas une option.
- Linux est pas un équivalent Windows " netstat? >_>
- Je pensais que Windows n'a pas netstat - il semble qu'il n'. 🙂 De toute façon, j'ai été en mesure de mettre en œuvre un Java-seule solution comme décrit dans ma réponse stackoverflow.com/a/11696077/62130
Vous devez vous connecter pour publier un commentaire.
J'ai été en mesure d'accrocher en
java.net.Socket
etjava.net.ServerSocket
et spy tous de nouvelles instances de ces classes. Le code complet peut être vu dans le référentiel source. Voici un aperçu de la démarche:Lors de la Prise ou à ServerSocket est instancié, la première chose dans son constructeur est un appel à
setImpl()
qui instancie l'objet qui implémente le support de la fonctionnalité. L'implémentation par défaut est une instance dejava.net.SocksSocketImpl
, mais il est possible de remplacer que par le réglage personnaliséjava.net.SocketImplFactory
parjava.net.Socket#setSocketImplFactory
etjava.net.ServerSocket#setSocketFactory
.C'est compliqué un peu par toutes les implémentations de
java.net.SocketImpl
étant colis-privé, mais avec un peu de réflexion qui n'est pas trop dur:La SocketImplFactory mise en œuvre pour l'espionnage sur toutes les prises qu'ils sont créés ressemble à quelque chose comme ceci:
Noter que setSocketFactory/setSocketImplFactory peut être appelée qu'une seule fois, de sorte que vous besoin d'avoir un seul essai, ce qui fait que (comme je l'ai), ou vous devez créer un static singleton (beurk!) pour la tenue que spy.
Alors la question est que la façon de savoir si la socket est fermée? Les deux Socket et ServerSocket avoir une méthode
isClosed()
, mais qui utilise un booléen interne de ces classes pour garder une trace de savoir si c'était fermé le SocketImpl exemple, n'a pas un moyen facile de vérifier si elle a été fermée. (BTW, les deux Socket et ServerSocket sont soutenus par une SocketImpl - il n'y a pas de "ServerSocketImpl".)Heureusement, le SocketImpl a une référence à la Prise ou à ServerSocket dont elle est la copie de sauvegarde. Ladite
setImpl()
les appels de méthodeimpl.setSocket(this)
ouimpl.setServerSocket(this)
, et il est possible d'obtenir cette référence de retour en appelantjava.net.SocketImpl#getSocket
oujava.net.SocketImpl#getServerSocket
.Une fois de plus, ces méthodes sont colis-privé, alors un peu de réflexion est nécessaire:
Noter que getSocket/getServerSocket ne peut pas être appelé à l'intérieur de la SocketImplFactory, parce Socket/ServerSocket définit seulement après la SocketImpl est retourné à partir de là.
Maintenant, il y a toute l'infrastructure nécessaire pour la vérification de nos tests, ce que nous voulons sur le Socket/ServerSocket:
Le code source complet est ici.
Je n'ai pas essayé moi-même, mais le JavaSpecialists bulletin d'information présente un problème similaire:
http://www.javaspecialists.eu/archive/Issue169.html
Au fond, il décrit une approche à l'aide AspectJ. Vous pourriez probablement mettre la coupe transverse (pointcut) autour du constructeur qui crée la socket, et le code qui enregistre création de la socket n'.