Puis-je savoir quel port est utilisé par la connexion Java RMI?
Si je souhaite connecter une application client Java à une application serveur Java à l'aide d'une connexion RMI, quel port dois-je ouvrir sur le serveur pour que l'application client puisse s'y connecter?
Je souhaite configurer un pare-feu sur le serveur, mais je ne sais pas quel port ouvrir.
RMI ne fonctionne généralement pas avec un pare-feu, car il utilise des ports imprévisibles (il commence par 1099, puis s'exécute avec un port aléatoire par la suite).
Dans ces situations, vous devez généralement recourir au tunneling RMI sur HTTP, ce qui est bien décrit ici .
Dans RMI, deux mécanismes distincts sont impliqués dans les ports:
1) Par défaut, le registre RMI utilise le port 1099
2) Le client et le serveur (stubs, objets distants) communiquent via des ports aléatoires, sauf si un port fixe a été spécifié lors de l'exportation d'un objet distant. La communication est démarrée via une fabrique de socket qui utilise 0 comme port de départ, ce qui signifie "utiliser tout port disponible" entre 0 et 65535.
Jusqu'à présent, toutes les réponses sont incorrectes. Le registre utilise normalement le port 1099, mais vous pouvez le changer. Mais ce n'est pas la fin de l'histoire. Les objets distants utilisent également des ports, et pas nécessairement 1099.
Si vous ne spécifiez pas de port lors de l'exportation , RMI utilise un port aléatoire. La solution est donc de spécifier un numéro de port lors de l'exportation . Et c’est un port qui a besoin d’être ouvert dans le pare-feu, le cas échéant.
Dans le cas où votre objet distant étend la UnicastRemoteObject
, appelez son constructeur super(port)
avec un numéro de port différent de zéro.
Dans le cas où UnicastRemoteObject
n'est pas étendu, indiquez un numéro de port différent de zéro à UnicastRemoteObject.exportObject()
.
Il y a plusieurs rides à cela.
Si vous n'utilisez pas de fabriques de sockets et que vous fournissez un numéro de port différent de zéro lors de l'exportation de votre premier objet distant, RMI partagera automatiquement ce port avec les objets distants exportés par la suite sans numéro de port spécifié ou en spécifiant zéro. Ce premier objet distant inclut un registre créé avec LocateRegistry.createRegistry().
. Ainsi, si vous créez une Registry
sur le port 1099, tous les autres objets exportés à partir de cette machine virtuelle Java peuvent partager le port 1099.
Si vous utilisez utilisez des fabriques de sockets et que votre RMIServerSocketFactory
a une implémentation judicieuse de equals()
, il en va de même que ci-dessus.
Dans les deux conditions, vous pouvez utiliser le même numéro de port explicite différent de zéro pour tous les objets distants, par exemple. createRegistry(1099)
suivi d'un nombre quelconque d'appels super(1099)
ou exportObject(..., 1099)
.
Vous définissez généralement le port sur le serveur à l'aide de la commande rmiregistry. Vous pouvez définir le port sur la ligne de commande ou il sera par défaut 1099
Si vous pouvez modifier le client, demandez-lui d’imprimer la référence distante et vous verrez quel port il utilise. Par exemple.
ServerApi server = (ServerApi) registry.lookup(ServerApi.RMI_NAME);
System.out.println("Got server handle " + server);
produira quelque chose comme:
Vous avez reçu le proxy du serveur [ServerApi, RemoteObjectInvocationHandler [UnicastRef [liveRef: [noeud final: 172.17.3.190: 9001, objID: [- 7c63fea8: ...
où vous pouvez voir que le port est 9001. Si la classe distante ne spécifie pas le port, cela changera lors des redémarrages. Si vous souhaitez utiliser un port fixe, vous devez vous assurer que le constructeur de la classe distante effectue quelque chose comme:
super(rmiPort)
Selon la manière dont vous implémentez le RMI, vous pouvez définir le port de registre (le registre est un "point de services unique"). Si vous ne définissez pas de port explicite, le registre utilisera le port 1099 par défaut. Dans certains cas, vous avez un pare-feu, et le pare-feu n'autorise pas votre client rmi à voir les talons et les objets derrière le registre, car ces objets s'exécutent de manière aléatoire, un port différent de celui utilisé par le registre, et ce port. est bloqué par le pare-feu - bien sûr ... Si vous utilisez RmiServiceExporter
pour configurer votre serveur RmiServer, vous pouvez utiliser la méthode rmiServiceExporter.setServicePort(port)
pour réparer le port RMI et ouvrir ce port dans le pare-feu.
Edit: Je résous ce problème avec ce message: http://www.mscharhag.com/Java/java-rmi-things-to-remember
En référence aux autres réponses ci-dessus, voici mon point de vue -
des ports sont impliqués à la fois du côté client et du côté serveur.
pour le côté serveur/distant, si vous exportez l'objet sans fournir de port, l'objet distant utilisera un port aléatoire pour écouter.
un client, lorsqu'il recherche l'objet distant, il utilisera toujours un port aléatoire de son côté et se connectera au port d'objet distant comme indiqué ci-dessus.