Ho un'applicazione Java che deve connettersi tramite socket a due server diversi su due macchine separate. Un server è stato configurato per l'ascolto sulle connessioni IPv4, mentre l'altro è stato configurato per l'ascolto sulle connessioni IPv6.Applicazione Java che desidera utilizzare contemporaneamente Inet4Address e Inet6Address
Ora, supponendo che "host1" sia il nome della macchina del server in ascolto sulle connessioni IPv4, mentre "host2" è il nome della macchina del server in ascolto sulle connessioni IPv6. Ho bisogno di ottenere un Inet4Address
per "host1" e un Inet6Address
per "host2" per creare una connessione socket a ciascun server, come ad esempio il seguente:
Inet4Address inet4 = (Inet4Address)InetAddress.getByName("host1");
InetSocketAddress soc4 = new InetSocketAddress(inet4, 7777);
...
Inet6Address inet6 = (Inet6Address)InetAddress.getByName("host2");
InetSocketAddress soc6 = new InetSocketAddress(inet6, 7777);
...
Tuttavia, la JVM di default preferisce utilizzare indirizzi IPv4 over Indirizzi IPv6 per motivi di compatibilità con le versioni precedenti. Quindi, nel codice precedente, il primo tentativo di connessione a "host1" ha esito positivo, ma il secondo tentativo di connessione a "host2" non riesce perché InetAddress.getByName("host2")
restituisce un Inet4Address
anziché Inet6Address
.
ho capito che posso impostare la proprietà di sistema java.net.preferIPv6Addresses
su true per preferire indirizzi IPv6 su IPv4, ma questo a sua volta fa sì che il secondo tentativo di connettersi a "host2" riesce, ma il primo tentativo di connettersi a "host1" fallito (!) perché InetAddress.getByName("host1")
restituisce un Inet6Address
anziché Inet4Address
.
La proprietà di sistema java.net.preferIPv6Addresses
viene letta solo una volta (vedere RigaInetAddress 212-218) e quindi non avrebbe alcun effetto anche se cambio il suo valore su falso dopo averlo impostato su true.
Quindi cosa posso fare in questo caso? Questo sembra un problema comune, quindi sicuramente deve esserci un modo per farlo.
Nota che posso ovviamente usare InetAddress.getByAddress()
e fornire l'indirizzo IP di ogni macchina in modo esplicito, invece di tornare un Inet4Address
e Inet6Address
, ma io non voglio fare questo a meno che non devo proprio. Quindi altre soluzioni per favore.
Oh, sto usando java 1.6.0_19 nel caso in cui sia importante.
Grazie!
Sì. Come ho detto, i due server stanno ascoltando rispettivamente le connessioni IPv4 e IPv6. Il casting che ho fatto nel codice di esempio sopra era solo per mostrare che volevo (e ho bisogno di) ottenere un 'Inet6Address' che poi devo passare a' InetSocketAddress' per connettermi a "host2" (il superamento di 'Inet4Address' causa un errore di connessione). Quindi, anche se uso sempre la "InetAddress" della superclasse, al di sotto di questo è in realtà "Inet4Address" o "Inet6Address", non è vero? E in questo caso, ho voluto rendere evidente il problema che sto avendo facendo esplicitamente il casting. – His
Sì, rimarrà solo 'Inet4Address' o' Inet6Address' e qual è il problema? IPv6 è compatibile con IPv4 non dovrebbe esserci alcun problema. –
Beh, non ne sono sicuro, perché non è quello che ho vissuto. Non riesco a usare un 'Inet6Address' (o' InetAddress' se vuoi) per connettermi al server in ascolto sulla connessione IPv4 - Ottengo un errore di connessione. Questo: 'nuovo InetSocketAddress (InetAddress.getByName (" host1 "), 7777)' con 'InetAddress.getByName (" host1 ")' la restituzione di Inet6Address/InetAddress, non funzionerà. Ma se 'InetAddress.getByName (" host1 ")' restituisce un 'Inet4Address/InetAddress', funzionerebbe. – His