您好,欢迎访问一九零五行业门户网

Java网络连通性如何测试

一般情况下,我们仅仅需要判断从一台机器是否可以访问(ping)到另一台机器,此时,可以简单的使用 java 类库中 java.net.inetaddress 类来实现,这个类提供了两个方法探测远程机器是否可达
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  地址发送到远端机器,以便远端机器可以通过该地址下载文件;或者远端机器提供某些服务,在某些事件发生时通知注册了获取这些事件的机器 (  常见于系统管理领域 ),因而在注册时需要提供本地的某个可达 ( 从远端 ) 地址。
虽然我们可以用 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)无法在此方法中应用。
具体过程是,枚举本地的每个网络地址,建立本地 socket,在某个端口上尝试连接远程地址,如果可以连接上,则说明该本地地址可达远程网络。
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 的 linklocal 地址也可以跳过测试
根据实际的需要,我们可以优先考虑选择使用 ipv4 或者 ipv6,提高判断的效率
判断本地地址和远程地址是否同为 ipv4 或者 ipv6
// 判断是 ipv4 还是 ipv6   if(!((localinetaddr instanceofinet4address) && (remoteinetaddr instanceofinet4address)   || (localinetaddr instanceofinet6address) && (remoteinetaddr instanceofinet6address))){   // 本地和远程不是同时是 ipv4 或者 ipv6,跳过这种情况,不作检测  break;   }
跳过本地地址和 linklocal 地址
if( localaddr.isloopbackaddress() ||       localaddr.isanylocaladdress() ||       localaddr.islinklocaladdress() ){       // 地址为本地环回地址,跳过      break;   }
以上就是java网络连通性如何测试的详细内容。
其它类似信息

推荐信息