Usiłuję opracować system, w którym istnieją różne węzły działające w innym systemie lub na różnych portach w tym samym systemie.
Teraz wszystkie węzły tworzą gniazdo z docelowym adresem IP jako adresem IP specjalnego węzła zwanego węzłem ładowania początkowego. Węzły następnie tworzą własne ServerSocket
i zaczynają nasłuchiwać połączeń.
Węzeł ładowania początkowego utrzymuje listę węzłów i zwraca je po zapytaniu.
Teraz potrzebuję, aby węzeł zarejestrował swój adres IP w węźle ładowania początkowego. Próbowałem użyć, cli.getInetAddress()
gdy klient łączy się ServerSocket
z węzłem ładowania początkowego, ale to nie działało.
- Potrzebuję klienta do zarejestrowania jego adresu IP PPP, jeśli jest dostępny;
- W przeciwnym razie adres IP sieci LAN, jeśli jest dostępny;
- W przeciwnym razie musi zarejestrować 127.0.0.1, zakładając, że jest to ten sam komputer.
Za pomocą kodu:
System.out.println(Inet4Address.getLocalHost().getHostAddress());
lub
System.out.println(InetAddress.getLocalHost().getHostAddress());
Mój adres IP połączenia PPP to: 117.204.44.192, ale powyższe zwraca mi 192.168.1.2
EDYTOWAĆ
Korzystam z następującego kodu:
Enumeration e = NetworkInterface.getNetworkInterfaces();
while(e.hasMoreElements())
{
NetworkInterface n = (NetworkInterface) e.nextElement();
Enumeration ee = n.getInetAddresses();
while (ee.hasMoreElements())
{
InetAddress i = (InetAddress) ee.nextElement();
System.out.println(i.getHostAddress());
}
}
Jestem w stanie uzyskać wszystkie adresy IP powiązane wszystkie NetworkInterface
, ale jak je rozróżnić? To jest wynik, który otrzymuję:
127.0.0.1
192.168.1.2
192.168.56.1
117.204.44.19
Odpowiedzi:
Ten sposób działa dobrze, gdy istnieje wiele interfejsów sieciowych. Zawsze zwraca preferowane wychodzące IP. Miejsce docelowe
8.8.8.8
nie musi być osiągalne.Connect
na gnieździe UDP ma następujący efekt: ustawia miejsce docelowe dla Send / Recv, odrzuca wszystkie pakiety z innych adresów i - co właśnie używamy - przenosi gniazdo do stanu „podłączonego”, ustawia odpowiednie pola. Obejmuje to sprawdzenie istnienia trasy do miejsca docelowego zgodnie z tablicą routingu systemu i odpowiednie ustawienie lokalnego punktu końcowego. Ostatnia część wydaje się być nieudokumentowana oficjalnie, ale wygląda na integralną cechę API gniazd Berkeley (efekt uboczny stanu „podłączonego” UDP), który działa niezawodnie zarówno w systemie Windows, jak i Linux w różnych wersjach i dystrybucjach.Tak więc ta metoda da adres lokalny, który będzie używany do łączenia się z określonym hostem zdalnym. Nie ustanowiono rzeczywistego połączenia, dlatego określony zdalny adres IP może być nieosiągalny.
Edytować:
Jak mówi @macomgil , w MacOS możesz to zrobić:
źródło
W najbardziej ogólnym przypadku może to być nieco trudne.
Na pierwszy rzut oka
InetAddress.getLocalHost()
powinien podać adres IP tego hosta. Problem polega na tym, że host może mieć wiele interfejsów sieciowych, a interfejs może być powiązany z więcej niż jednym adresem IP. Co więcej, nie wszystkie adresy IP będą dostępne poza urządzeniem lub siecią LAN. Mogą to być na przykład adresy IP wirtualnych urządzeń sieciowych, adresy IP prywatnych sieci i tak dalej.Oznacza to, że adres IP został zwrócony przez
InetAddress.getLocalHost()
może być niewłaściwy do użycia.Jak sobie z tym poradzić?
NetworkInterface.getNetworkInterfaces()
wszystkich znanych interfejsów sieciowych na hoście, a następnie iteracja po adresach każdego NI.InetAddress.getByName()
do wyszukania podstawowego adresu IP. (Ale jak to zdobyć i jak radzić sobie z modułem równoważenia obciążenia opartym na DNS?)Podsumowując,
InetAddress.getLocalHost()
zazwyczaj działa, ale może być konieczne podanie alternatywnej metody dla przypadków, w których kod jest uruchamiany w środowisku z „skomplikowanymi” sieciami.W rzeczywistości interfejs API InetAddress zapewnia metody testowania adresów pętli zwrotnej, linków lokalnych, lokalnych witryn, adresów multiemisji i rozgłaszania. Możesz ich użyć, aby ustalić, który z odzyskanych adresów IP jest najbardziej odpowiedni.
źródło
use getLocalHost().getHostAddress()
coś opublikujesz, możesz to zobaczyć0.0.0.0
, patrząc z innego komputera w sieci. Jest to wyjaśnione tutaj to jest to, co się ze mną stało, kiedy używałem Gazebo na dwóch komputerachOpublikowanie tutaj przetestowanego kodu obejścia niejednoznaczności IP z https://issues.apache.org/jira/browse/JCS-40 (InetAddress.getLocalHost () niejednoznaczne w systemach Linux):
źródło
W tym celu można użyć klasy InetAddress języka Java .
Dane wyjściowe dla mojego systemu =
IP of my system is := 10.100.98.228
getHostAddress () powraca
LUB możesz też zrobić
Wyjście =
IP of my system is := RanRag-PC/10.100.98.228
źródło
Gdy szukasz adresu „lokalnego”, należy pamiętać, że każde urządzenie ma nie tylko jeden interfejs sieciowy, a każdy interfejs może mieć własny adres lokalny. Co oznacza, że twój komputer zawsze posiada kilka „lokalnych” adresów.
Różne adresy „lokalne” zostaną automatycznie wybrane do użycia podczas łączenia się z różnymi punktami końcowymi. Na przykład, kiedy łączysz się
google.com
, używasz lokalnego adresu „zewnętrznego”; ale kiedy łączysz się z twoimlocalhost
, twój lokalny adres jest zawszelocalhost
sam, ponieważ localhost jest tylko zapętleniem.Poniżej pokazano, jak znaleźć adres lokalny podczas komunikacji z
google.com
:źródło
Przykład w scala (przydatny w pliku sbt):
źródło
EDYCJA 1: Zaktualizowany kod, ponieważ poprzedni link już nie istnieje
AKTUALNA WERSJA: To przestało działać
Mamy nadzieję, że ten fragment pomoże ci to osiągnąć:
źródło
whatismyip.com
był wyłączony przez pewien czas, twoja aplikacja również byłaby wyłączona :(. Albo zwróci śmieciowe dane i spowoduje nieoczekiwane zachowanie. Zwraca to również outter większość adresów IP wykrywanych przezwhatismyip.com
, niekoniecznie adres IP maszyny, której używasznajpierw zaimportuj klasę
w klasie
źródło
Możesz użyć
java.net.InetAddress
API. Spróbuj tego :źródło
źródło
To jest działający przykład AKCEPTOWANEJ odpowiedzi powyżej! Ta klasa NetIdentity będzie przechowywać zarówno wewnętrzny adres IP hosta, jak i lokalną pętlę zwrotną. Jeśli korzystasz z serwera opartego na systemie DNS, jak wspomniano powyżej, konieczne może być dodanie dodatkowych kontroli lub przejście do pliku konfiguracji trasy.
Kiedy uruchamiam ten kod, faktycznie otrzymuję taki wydruk:
Na mój użytek konfiguruję serwer Upnp, co pomogło zrozumieć „wzorzec”, którego szukałem. Niektóre zwracane obiekty to Adaptery Ethernet, Adaptery sieciowe, Adaptery Sieci Wirtualnej, Sterowniki i Adaptery Klienta VPN. Nie wszystko też ma adres. Więc będziesz chciał pominąć obiekty interfejsu, które tego nie robią.
Możesz również dodać to do pętli dla prądu
NetworkInterface i
W wynikach zobaczysz informacje podobne do następujących:
źródło
Użyj InetAddress.getLocalHost (), aby uzyskać adres lokalny
źródło
źródło
Raczej uproszczone podejście, które wydaje się działać ...
źródło
Otrzyma adres IP twojej sieci, jeśli twoje urządzenie jest częścią sieci
źródło
Zwykle, gdy próbuję znaleźć mój publiczny adres IP, taki jak cmyip.com lub www.iplocation.net , używam tego sposobu:
źródło
Ponieważ mój system (podobnie jak wiele innych systemów) miał różne interfejsy sieciowe.
InetAddress.getLocalHost()
lubInet4Address.getLocalHost()
po prostu zwrócił taki, którego nie chciałem. Dlatego musiałem zastosować to naiwne podejście.Uważaj tylko, aby w tym podejściu wiedziałem już, że mój pożądany adres IP znajduje się w
192.168.2
podsieci.źródło
źródło