Généralement, il nous suffit de déterminer si une machine peut accéder (pinger) à une autre machine. Pour le moment, nous pouvons simplement utiliser la classe java.net.InetAddress dans la bibliothèque de classes Java pour y parvenir. détecter si la machine distante est accessible
boolean isReachable(int timeout) // 测试地址是否可达 boolean isReachable(NetworkInterface netif, int ttl, int timeout) // 测试地址是否可达.
En termes simples, la méthode ci-dessus consiste à construire un objet InetAddress via l'adresse IP de la machine distante, puis à appeler sa méthode isReachable pour tester l'accessibilité réseau de la machine appelante et de la machine distante . Notez que la machine distante peut avoir plusieurs adresses IP, vous souhaiterez donc peut-être tester tous les scénarios de manière itérative.
void isAddressAvailable(String ip){ try{ InetAddress address = InetAddress.getByName(ip);//ping this IP if(address instanceof java.net.Inet4Address){ System.out.println(ip + " is ipv4 address"); }else if(address instanceof java.net.Inet6Address){ System.out.println(ip + " is ipv6 address"); }else{ System.out.println(ip + " is unrecongized"); } if(address.isReachable(5000)){ System.out.println("SUCCESS - ping " + IP + " with no interface specified"); }else{ System.out.println("FAILURE - ping " + IP + " with no interface specified"); } System.out.println("\n-------Trying different interfaces--------\n"); Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces(); while(netInterfaces.hasMoreElements()) { NetworkInterface ni = netInterfaces.nextElement(); System.out.println( "Checking interface, DisplayName:" + ni.getDisplayName() + ", Name:" + ni.getName()); if(address.isReachable(ni, 0, 5000)){ System.out.println("SUCCESS - ping " + ip); }else{ System.out.println("FAILURE - ping " + ip); } Enumeration<InetAddress> ips = ni.getInetAddresses(); while(ips.hasMoreElements()) { System.out.println("IP: " + ips.nextElement().getHostAddress()); } System.out.println("-------------------------------------------"); } }catch(Exception e){ System.out.println("error occurs."); e.printStackTrace(); } }
Sortie du programme :
--------------START-------------- 10.13.20.70 is ipv4 address SUCCESS - ping 10.13.20.70 with no interface specified -------Trying different interfaces-------- Checking interface, DisplayName:MS TCP Loopback interface, Name:lo FAILURE - ping 10.13.20.70 IP: 127.0.0.1 ------------------------------------------- Checking interface, DisplayName:Intel(R) Centrino(R) Advanced-N 6200 AGN - Teefer2 Miniport, Name:eth0 FAILURE - ping 10.13.20.70 IP: 9.123.231.40 ------------------------------------------- Checking interface, DisplayName:Intel(R) 82577LM Gigabit Network Connection - Teefer2 Miniport, Name:eth2 SUCCESS - ping 10.13.20.70 ------------------------------------------- Checking interface, DisplayName:WAN (PPP/SLIP) Interface, Name:ppp0 SUCCESS - ping 10.13.20.70 IP: 10.0.50.189 ------------------------------------------- --------------END--------------
Comme vous pouvez le voir ci-dessus, l'utilisation de isReachable peut être utilisée pour déterminer l'accessibilité du réseau distant sans spécifier d'interface, mais cela ne peut pas distinguer de quelle interface réseau le paquet de données est envoyé. (s'il existe plusieurs interfaces réseau locales) ; la version avancée d'isReachable peut spécifier à partir de quelle interface réseau locale tester, afin que vous puissiez savoir avec précision à quelle interface réseau locale le réseau distant peut se connecter.
Cependant, Java lui-même ne fournit aucune méthode pour déterminer quelle adresse IP locale peut se connecter au réseau distant, et l'interface de programmation réseau Java ne fournit pas de méthode pour accéder aux paquets de données du protocole ICMP, cela est donc réalisé via le réseau ICMP inaccessible. paquets de données. C'est également impossible (bien sûr, cela peut être implémenté en utilisant JNI, mais cela dépend de la plate-forme système. À ce stade, vous pouvez considérer la méthode proposée dans la section suivante de cet article).
Dans certains cas, nous pouvons vouloir déterminer quelle adresse de réseau local peut se connecter au réseau distant, afin que le réseau distant puisse se reconnecter au réseau local pour utiliser certains services ou émettre certaines notifications. Un scénario d'application typique est qu'un service de transfert de fichiers (tel que FTP) est démarré localement et qu'une adresse IP locale doit être envoyée à la machine distante afin que la machine distante puisse télécharger des fichiers via cette adresse ou que la machine distante fournisse certaines informations. Le service informe la machine enregistrée pour obtenir ces événements lorsque certains événements se produisent (courants dans le domaine de la gestion du système), de sorte qu'une adresse locale accessible (à distance) doit être fournie lors de l'enregistrement.
Bien que nous puissions utiliser la méthode InetAddress.isReachabl pour déterminer quelle interface réseau locale peut être connectée à la lecture à distance, mais comme une seule interface réseau peut être configurée avec plusieurs adresses IP, elle ne convient pas ici. Nous pouvons utiliser Socket pour établir une éventuelle connexion TCP, puis déterminer si une adresse IP locale est accessible au réseau distant. Nous utilisons la méthode connect dans la classe java.net.Socket
void connect(SocketAddress endpoint, int timeout) //使用Socket连接服务器,指定超时的时间
Cette méthode nécessite un port distant, qui peut être n'importe quel port de service ouvert basé sur le protocole TCP (tel que le port de service ECHO 7 généralement ouvert, le port de service Linux SSH 22, etc.). En fait, la connexion TCP établie est placée dans la file d'attente de connexion par la pile de protocoles puis distribuée à divers services d'application qui traitent réellement les données. Étant donné qu'UDP n'a pas de processus de connexion, les services basés sur UDP (tels que SNMP) ne peuvent pas l'être. appliquée dans cette méthode.
Le processus spécifique consiste à énumérer chaque adresse de réseau local, à établir un socket local et à essayer de se connecter à l'adresse distante sur un certain port. Si elle peut être connectée, cela signifie que l'adresse locale peut atteindre le réseau distant.
void printReachableIP(InetAddress remoteAddr, int port){ String retIP = null; Enumeration<NetworkInterface> netInterfaces; try{ netInterfaces = NetworkInterface.getNetworkInterfaces(); while(netInterfaces.hasMoreElements()) { NetworkInterface ni = netInterfaces.nextElement(); Enumeration<InetAddress> localAddrs = ni.getInetAddresses(); while(localAddrs.hasMoreElements()){ InetAddress localAddr = localAddrs.nextElement(); if(isReachable(localAddr, remoteAddr, port, 5000)){ retIP = localAddr.getHostAddress(); break; } } } } catch(SocketException e) { System.out.println( "Error occurred while listing all the local network addresses."); } if(retIP == null){ System.out.println("NULL reachable local IP is found!"); }else{ System.out.println("Reachable local IP is found, it is " + retIP); } } boolean isReachable(InetAddress localInetAddr, InetAddress remoteInetAddr, int port, int timeout) { booleanisReachable = false; Socket socket = null; try{ socket = newSocket(); // 端口号设置为 0 表示在本地挑选一个可用端口进行连接 SocketAddress localSocketAddr = new InetSocketAddress(localInetAddr, 0); socket.bind(localSocketAddr); InetSocketAddress endpointSocketAddr = new InetSocketAddress(remoteInetAddr, port); socket.connect(endpointSocketAddr, timeout); System.out.println("SUCCESS - connection established! Local: " + localInetAddr.getHostAddress() + " remote: " + remoteInetAddr.getHostAddress() + " port" + port); isReachable = true; } catch(IOException e) { System.out.println("FAILRE - CAN not connect! Local: " + localInetAddr.getHostAddress() + " remote: " + remoteInetAddr.getHostAddress() + " port" + port); } finally{ if(socket != null) { try{ socket.close(); } catch(IOException e) { System.out.println("Error occurred while closing socket.."); } } } return isReachable; }
Résultats d'exécution
--------------START-------------- FAILRE - CAN not connect! Local: 127.0.0.1 remote: 10.8.1.50 port22 FAILRE - CAN not connect! Local: 9.123.231.40 remote: 10.8.1.50 port22 SUCCESS - connection established! Local: 10.0.50.189 remote: 10.8.1.50 port22 Reachable local IP is found, it is 10.0.50.189 --------------END--------------
Lorsqu'il y a IPv4 et IPv6 dans l'environnement réseau, c'est-à-dire lorsque la machine a à la fois une adresse IPv4 et une adresse IPv6, nous pouvons apporter quelques optimisations au programme, telles que
Depuis le La différence entre les adresses IPv4 et IPv6 ne peut pas accéder les unes aux autres, donc seule l'accessibilité entre les adresses IPv4 et les adresses IPv6 doit être déterminée.
Vous n'avez pas besoin de porter de jugement sur l'adresse de retour IPv4, et vous pouvez sauter le test pour l'adresse IPv6 Linklocal
Selon les besoins réels, nous pouvons donner la priorité à l'utilisation d'IPv4 ou d'IPv6 pour améliorer l'efficacité du jugement
Déterminez si l'adresse locale et l'adresse distante sont à la fois IPv4 ou IPv6
// 判断是 IPv4 还是 IPv6 if(!((localInetAddr instanceofInet4Address) && (remoteInetAddr instanceofInet4Address) || (localInetAddr instanceofInet6Address) && (remoteInetAddr instanceofInet6Address))){ // 本地和远程不是同时是 IPv4 或者 IPv6,跳过这种情况,不作检测 break; }
Ignorez l'adresse locale et l'adresse LinkLocal
if( localAddr.isLoopbackAddress() || localAddr.isAnyLocalAddress() || localAddr.isLinkLocalAddress() ){ // 地址为本地环回地址,跳过 break; }
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!