J'ai une application Java qui doit se connecter via des sockets à deux serveurs différents sur deux machines distinctes. Un serveur a été configuré pour écouter les connexions IPv4, tandis que l'autre a été configuré pour écouter les connexions IPv6. Maintenant, en supposant que "host1" est le nom de l'ordinateur du serveur écoutant les connexions IPv4, alors que "host2" est le nom de l'ordinateur du serveur écoutant les connexions IPv6. Je dois obtenir un Inet4Address
pour « host1 » et un Inet6Address
pour « host2 » pour créer une connexion de socket pour chaque serveur, telles que les suivantes:Application Java souhaitant utiliser à la fois Inet4Address et Inet6Address en même temps
Inet4Address inet4 = (Inet4Address)InetAddress.getByName("host1");
InetSocketAddress soc4 = new InetSocketAddress(inet4, 7777);
...
Inet6Address inet6 = (Inet6Address)InetAddress.getByName("host2");
InetSocketAddress soc6 = new InetSocketAddress(inet6, 7777);
...
Cependant, la machine virtuelle Java par défaut préfère utiliser les adresses IPv4 sur Adresses IPv6 pour des raisons de compatibilité descendante. Ainsi, dans le code ci-dessus, la première tentative de connexion à "host1" réussit, mais la deuxième tentative de connexion à "host2" échoue car InetAddress.getByName("host2")
renvoie un Inet4Address
au lieu de Inet6Address
. Je comprends que je peux définir la propriété système java.net.preferIPv6Addresses
sur true pour préférer les adresses IPv6 sur IPv4, mais cela entraîne la réussite de la deuxième tentative de connexion à "host2", mais la première tentative de connexion à "host1" a échoué (!) car InetAddress.getByName("host1")
renvoie Inet6Address
au lieu de Inet4Address
. La propriété système java.net.preferIPv6Addresses
est lue une seule fois (voir InetAddress ligne 212-218) et n'a donc aucun effet même si je la ramène à false après l'avoir définie sur true.
Alors, que puis-je faire dans ce cas? Cela semble être un problème commun, alors il doit sûrement y avoir déjà un moyen de le faire.
Notez que je peux bien sûr utiliser InetAddress.getByAddress()
et de fournir l'adresse IP de chaque machine explicitement au lieu de retourner un Inet4Address
et Inet6Address
, mais je ne veux pas le faire à moins d'avoir vraiment. Donc, d'autres solutions s'il vous plaît.
Oh, j'utilise java 1.6.0_19 au cas où cela serait important.
Merci!
Je le fais. Comme je l'ai dit, les deux serveurs écoutent respectivement les connexions IPv4 et IPv6. Le casting que j'ai fait dans l'exemple ci-dessus était juste pour montrer que je voulais (et je dois) obtenir un 'Inet6Address' que j'ai ensuite besoin de passer à' InetSocketAddress' pour se connecter à "host2" (passer un 'Inet4Address' provoquer un échec de connexion). Donc, même si j'utilise tout le temps la superclasse 'InetAddress', en dessous il y a soit' Inet4Address' ou 'Inet6Address', n'est-ce pas? Et dans ce cas, je voulais rendre évident le problème que j'ai en faisant le casting explicitement. – His
Oui, il restera toujours "Inet4Address" ou "Inet6Address", et quel est le problème? IPv6 est compatible avec IPv4 il ne devrait pas y avoir de problème. –
Eh bien, je ne suis pas sûr, parce que ce n'est pas ce que j'ai vécu. Je ne peux pas utiliser un 'Inet6Address' (ou' InetAddress' si vous voulez) pour se connecter au serveur en écoutant la connexion IPv4 - j'obtiens un échec de connexion. Ceci: 'new InetSocketAddress (InetAddress.getByName (" host1 "), 7777)' avec 'InetAddress.getByName (" host1 ")' renvoyer une Inet6Address/InetAddress, ne fonctionnera pas. Mais si 'InetAddress.getByName (" host1 ")' renvoie un 'Inet4Address/InetAddress', cela fonctionnerait. – His