ホームページ > Java > &#&チュートリアル > Java ネットワーク接続をテストする方法

Java ネットワーク接続をテストする方法

王林
リリース: 2023-05-04 15:49:06
転載
1266 人が閲覧しました

通常、あるマシンが別のマシンにアクセス (Ping) できるかどうかを判断するだけで済みます。現時点では、Java クラス ライブラリの java.net.InetAddress クラスを使用するだけでこれを実現できます。このクラスは次の機能を提供します。リモート マシンが到達可能かどうかを検出する 2 つのメソッド

boolean isReachable(int timeout) // 测试地址是否可达 boolean isReachable(NetworkInterface netif, int ttl, int timeout)  // 测试地址是否可达.
ログイン後にコピー

簡単に言うと、上記のメソッドは、リモート マシンの IP アドレスを使用して InetAddress オブジェクトを構築し、その isReachable メソッドを呼び出してネットワークをテストします。発信側マシンとリモート マシン間のアクセシビリティ。リモート マシンには複数の IP アドレスがある場合があるため、すべてのシナリオを繰り返しテストすることをお勧めします。

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();          }         }
ログイン後にコピー

プログラム出力:

--------------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--------------
ログイン後にコピー

上記からわかるように、isReachable を使用すると、インターフェイスを指定せずにリモート ネットワークの到達可能性を判断できますが、これではどこにあるかを区別できません。データ パケットの送信元 (ローカル ネットワーク インターフェイスが複数ある場合)、isReachable の高度なバージョンでは、どのローカル ネットワーク インターフェイスからテストするかを指定できるため、リモートのローカル ネットワーク インターフェイスがどれであるかを正確に知ることができます。ネットワークに接続できます。

ただし、Java 自体には、どのローカル IP アドレスがリモート ネットワークに接続できるかを判断する方法が提供されておらず、Java ネットワーク プログラミング インターフェイスにも ICMP プロトコル データ パケットにアクセスする方法が提供されていないため、ネットワークICMP に到達できず、パッケージで実装することも不可能です (もちろん JNI を使用して実装できますが、システム プラットフォームに依存します)。現時点では、この記事の次のセクションで提案する方法を検討できます。 。

場合によっては、リモート ネットワークがローカルに接続して特定のサービスを使用したり、特定の通知を発行したりできるように、どのローカル ネットワーク アドレスがリモート ネットワークに接続できるかを判断することが必要になることがあります。典型的なアプリケーション シナリオでは、ファイル転送サービス (FTP など) がローカルで開始され、リモート マシンがこのアドレスを通じてファイルをダウンロードできるように、ローカル IP アドレスをリモート マシンに送信する必要があるか、リモート マシンが特定の IP アドレスを提供する必要があります。このサービスは、特定のイベントが発生したときに、これらのイベントを取得するように登録されたマシンに通知します (システム管理の分野では一般的)。そのため、登録時に (リモートから) 到達可能なローカル アドレスを指定する必要があります。

InetAddress.isReachabl メソッドを使用して、どのローカル ネットワーク インターフェイスをリモート プレイに接続できるかを決定できますが、単一のネットワーク インターフェイスが複数の IP アドレスで構成できるため、ここでは適切ではありません。 Socket を使用して TCP 接続を確立し、ローカル IP アドレスがリモート ネットワークに到達可能かどうかを判断できます。 java.net.Socket クラスの connect メソッドを使用します。

void connect(SocketAddress endpoint, int timeout)  //使用Socket连接服务器,指定超时的时间
ログイン後にコピー

このメソッドにはリモート ポートが必要です。リモート ポートは、TCP プロトコルに基づく任意のオープン サービスのポート (一般的にオープンな ECHO サービス ポートなど) にすることができます。 7、Linux SSH サービス ポート 22 など)。実際、確立された TCP 接続はプロトコル スタックによって接続キューに置かれ、実際にデータを処理するさまざまなアプリケーション サービスに分散されますが、UDP には接続プロセスがないため、UDP ベースのサービス (SNMP など) は利用できません。この方法で適用されます。

具体的なプロセスは、各ローカル ネットワーク アドレスを列挙し、ローカル ソケットを確立し、特定のポートでリモート アドレスへの接続を試行することです。接続できた場合は、ローカル アドレスがネットワークに到達できることを意味します。リモートネットワーク。

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;   }
ログイン後にコピー

実行結果

--------------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--------------
ログイン後にコピー

ネットワーク環境にIPv4とIPv6が存在する場合、つまりマシンがIPv4アドレスとIPv6アドレスの両方を持っている場合、いくつかの最適化を行うことができます。

  • IPv4 アドレスと IPv6 アドレスは相互にアクセスできないため、IPv4 アドレス間および IPv6 アドレス間の到達可能性を判断することのみが必要です。

  • IPv4 リターン アドレスを判断する必要はなく、IPv6 リンクローカル アドレスのテストをスキップできます

  • 実際の結果によると、 IPv4 か IPv6 を優先して判定の効率を上げることができます

ローカルアドレスとリモートアドレスが両方とも IPv4 か IPv6 かを判定

// 判断是 IPv4 还是 IPv6   if(!((localInetAddr instanceofInet4Address) && (remoteInetAddr instanceofInet4Address)   || (localInetAddr instanceofInet6Address) && (remoteInetAddr instanceofInet6Address))){   // 本地和远程不是同时是 IPv4 或者 IPv6,跳过这种情况,不作检测  break;   }
ログイン後にコピー

Skipローカル アドレスと LinkLocal Address

if( localAddr.isLoopbackAddress() ||       localAddr.isAnyLocalAddress() ||       localAddr.isLinkLocalAddress() ){       // 地址为本地环回地址,跳过      break;   }
ログイン後にコピー

以上がJava ネットワーク接続をテストする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート