Maison > Java > javaDidacticiel > Comment tester la connectivité réseau Java

Comment tester la connectivité réseau Java

王林
Libérer: 2023-05-04 15:49:06
avant
1264 Les gens l'ont consulté

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)  // 测试地址是否可达.
Copier après la connexion

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();          }         }
Copier après la connexion

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--------------
Copier après la connexion

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连接服务器,指定超时的时间
Copier après la connexion

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;   }
Copier après la connexion

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--------------
Copier après la connexion

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;   }
Copier après la connexion

Ignorez l'adresse locale et l'adresse LinkLocal

if( localAddr.isLoopbackAddress() ||       localAddr.isAnyLocalAddress() ||       localAddr.isLinkLocalAddress() ){       // 地址为本地环回地址,跳过      break;   }
Copier après la connexion

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!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal