1. 程式人生 > >Java 中執行CMD命令(copy/ping)

Java 中執行CMD命令(copy/ping)

java實現一些cmd命令

最近在專案中需要用到一些cmd命令,於是利用java提供的Runtime.getRuntime().exec(cmd)方法執行,現對使用的一些命令做一下小結。:

  • 執行copy 命令
  • 執行ping命令

執行copy命令

copy命令主要用於複製檔案,在windows環境下,copy命令的格式一般為:copy 原始檔 目的資料夾,比如:copy d:\test\mc2.db e:\test\。
如果想要實現不同主機之間的檔案copy,首先需要保證這兩個主機在網路上是可以連通的,其次可以採取共享檔案的方式,使得執行copy命令的主機能夠直接訪問共享檔案。
需要注意的是,如果在原始檔所在路徑或者目標資料夾路徑中存在空格,這個路徑需要使用雙引號引起來。下面為一個具體的實現例子:

public void copyfile(){
    String orig = "\\\\192.168.1.1\\db\\mc2.db"; //原始檔
    String dest = "\"D:\\test test\\"";  //有空格需要使用雙引號
    String cmd = "cmd /c copy"+orig+" "+dest;
    try{
        Runtime.getRuntime().exec(cmd);
    }catch(IOException e){
        e.printStackTrace();
    }
}

執行ping命令

ping命令主要用於測試與某臺主機的網路連通性,在dos環境下其使用方式比較簡單,只需要按照:ping 目的主機IP地址,比如:ping 192.168.1.1 ,這種方式即可,不過在java中測試主機的連通性不止使用cmd命令這一種。
下面介紹三種在java中測試主機是否連通的方法:

1、使用上面執行cmd命令的方式執行一般的ping命令。
這種方式簡單易行,但是當對端機器開啟防火牆時,這種方式無法成功。

2、簡單的使用 Java 類庫中 java.net.InetAddress 類來實現,這個類提供了兩個方法探測遠端機器是否可達:

isReachable(int timeout)
isReachable(NetworkInterface netif, int
ttl, int timeout)

上述方法就是通過遠端機器的IP地址構造InetAddress物件,然後呼叫其isReachable方法,測試呼叫機器和遠端機器的網路可達性。注意到遠端機器可能有多個IP地址,因而可能要迭代的測試所有的情況。
案例1:

 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();   
        }         
 } 

從上可以看出isReachable的用法,可以不指定任何介面來判斷遠端網路的可達性,但這不能區分出資料包是從那個網路介面發出去的 (如果本地有多個網路介面的話);而高階版本的isReachable則可以指定從本地的哪個網路介面測試,這樣可以準確的知道遠端網路可以連通本地的哪個網路介面。
但是,Java本身沒有提供任何方法來判斷本地的哪個IP地址可以連通遠端網路,Java網路程式設計介面也沒有提供方法來訪問ICMP協議資料包,因而通過ICMP的網路不可達資料包實現這一點也是不可能的 (當然可以用JNI來實現,但就和系統平臺相關了 ), 此時可以考慮本文下一節提出的方法。

3、指定本地和遠端網路地址,判斷兩臺機器之間的可達性
在某些情況下,我們可能要確定本地的哪個網路地址可以連通遠端網路,以便遠端網路可以回連到本地使用某些服務或發出某些通知。一個典型的應用場景是,本地啟動了檔案傳輸服務(如FTP),需要將本地的某個IP地址傳送到遠端機器,以便遠端機器可以通過該地址下載檔案;或者遠端機器提供某些服務,在某些事件發生時通知註冊了獲取這些事件的機器 ( 常見於系統管理領域 ),因而在註冊時需要提供本地的某個可達 (從遠端) 地址。
雖然我們可以用InetAddress.isReachabl方法判斷出本地的哪個網路介面可連通遠端玩過,但是由於單個網路介面是可以配置多個IP地址的,因而在此並不合適。我們可以使用Socket建立可能的TCP連線,進而判斷某個本地 IP 地址是否可達遠端網路。我們使用java.net.Socket 類中的connect方法。

 connect(SocketAddress endpoint, int timeout)  //使用Socket連線伺服器,指定超時的時間 

這種方法需要遠端的某個埠,該埠可以是任何基於TCP協議的開放服務的埠(如一般都會開放的ECHO服務埠7,Linux的SSH服務埠22等)。實際上,建立的TCP連線被協議棧放置在連線佇列,進而分發到真正處理資料的各個應用服務,由於UDP沒有連線的過程,因而基於UDP的服務(如 SNMP)無法在此方法中應用。
具體過程是,列舉本地的每個網路地址,建立本地Socket,在某個埠上嘗試連線遠端地址,如果可以連線上,則說明該本地地址可達遠端網路。
案例2:

 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;   
 }