用純JAVA語言實現讀取MAC地址

來源:互聯網
上載者:User
本文介紹如何在WindowXP/NT/2000環境中,編寫純Java程式,執行外部命令IPCONFIG,並通過分析該命令的輸入資料流而獲得原生MAC地址的編程方法。

  1 引言

  用Java編寫的程式,可以很方便地運行在各種平台的環境。但在實際的開發過程中,有時不得不涉及一些底層的編程。比如為了防止軟體盜用,我們 希望軟體只能在指定電腦上運行,所以需要程式讀取該機區分於其它電腦的硬體特徵,如MAC地址等。作為一種跨平台語言,給Java語言提出了挑戰。本 文正是針對該問題,提出一種直接用純Java語言,讀去MAC地址的編程方法。

  我們知道,在每一個Java應用程式中都存在著一個與其運行環境相聯絡的Runtime對象。該對象可執行外部命令、查可用記憶體等。而多數操作 系統都提供有查詢該機MAC地址的命令。如在Microsoft的作業系統中,命令IPCONFIG等。本文的思路是在程式中運行一個外部命令,將該命令 的運行結果作為一個流(Stream),讀取並分析之,進而實現擷取MAC地址的目的。

  2 Runtime類

  在每一個Java 應用程式裡面,都有惟一的一個Runtime 對象。通過這個Runtime 對象,應用程式可以與其運行環境發生相互作用。

  一般不執行個體化一個Runtime對象。但是可以通過調用靜態方法Runtime.getRuntime( )而獲得對當前Runtime對象的引用。Runtime 類的大多數方法是執行個體方法。

  Runtime 對象的作用主要有:執行外部命令;返回空閑記憶體;運行記憶體回收行程;載入動態庫等。

  Applets和其他不可信賴的程式由於沒有引起一個安全異常(SecurityException)而不能調用任何的Runtime方法。

  下面的例子示範了怎樣使用Runtime 對象運行一個外部命令。


  Process process = Runtime.getRuntime().exec("cmd.exe /c dir");
  process.waitFor();
  :

  Runtime.getRuntime()返回當前應用程式的Runtime對象,該對象的exec()方法指示Java虛擬機器建立一個子進程 執行指定的可執行程式,並返回與該子進程對應的Process對象執行個體。通過Process可以控制該子進程的執行或擷取該子進程的資訊。第二條語句的目 的是等待子進程完成後再往下執行。

  上面的程式在運行時會執行dir命令。如果在Windows95/98下,命令格式可以寫成"command.exe /c dir"。開關/C指明後面跟隨的字串是命令,並在執行命令後關閉DOS 視窗。

  方法exec還可以開啟一個不可執行檔程式,但該檔案存在相關 App程式。以開啟一個word文檔Mydoc.doc檔案為例,Java中可以有以下兩種寫法:

 exec(""cmd /E:ON /c start MyDoc.doc"");
  exec(" c:Program FilesMicrosoft Officeofficewinword.exe .mydoc.doc");

  在第一種方式中,被執行的命令是start Mydoc.doc,開關E:ON 指定DOS 命令處理器允許命令擴充,而start 命令會開啟一個單獨的視窗執行所提供的命令。

  執行一個有標準輸出的DOS命令,程式執行完後往往不會自動關閉,從而導致Java應用程式阻塞在waitfor( )。導致該現象的原因可能是該命令的輸出比較多,而運行視窗的輸出緩衝區不夠大。解決的辦法是,利用Java的Process類提供的方法讓Java虛擬 機截獲DOS啟動並執行標準輸出,在waitfor()命令之前讀出該緩衝區的內容。以運行命令dir為例,典型的程式如下:

 :
  String line;
  Process process = Runtime.getRuntime().exec("cmd /c dir");
  BufferedReader bufferedReader = new BufferedReader ( new InputStreamReader(process.getInputStream()));
  while ( (line = bufferedReader.readLine()) != -1) System. out.println(line);
  process.waitFor( );
  :

  3 Process

  Runtime.exec方法建立一個本機進程,並返回 Process 子類的一個執行個體,該執行個體可用來控制進程並擷取相關資訊。

  抽象類別Process封裝了一個進程(process),一個正在執行的程式。它主要被當作由Runtime類中的exec( )方法所建立的對象的類型的超類。在抽象類別Process中,主要包含了如下一些抽象方法。

  InputStream getInputStream( ):返回一個從進程的out輸出資料流中讀輸入的輸入資料流。

  OutputStream getOutputStream( ):返回一個從進程的in輸入資料流中寫輸出的輸出資料流。

  int waitFor( ) throws InterruptedException:返回由進程返回的退出碼。這個方法直到調用它的進程中止,才會返回。

  4 程式編寫

  我們先來分析ipconfig/all的輸出格式:


圖1

  從圖1中我們看到MAC地址包含的行為:“ Physical Address. . . . . . . . . : 00-10-DC-A9-0B-2C”。為了找到MAC地址,我們一行一行讀取字元,只要找到字串“ Physical Address. . . . . . . . . :”,就可以找到MAC地址了。下面是實現的程式片段:


  Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
  BufferedReader bufferedReader =
  new BufferedReader(new InputStreamReader (process.getInputStream()));
  while ( (line=bufferedReader.readLine()) != null){
  if(line.indexOf("Physical Address. . . . . . . . . :") != -1){
  if(line.indexOf(":") != -1){
  physicalAddress = line.substring(line.indexOf(":")+2);
  :

  在上面的程式中,為了讀取命令輸出的字元,利用子進程process產生了一個資料流緩衝區。

  依據上面的代碼,我們編寫了一個類ReadMAC,見下面程式的原始碼:

import java.io.*;
  public class ReadMAC {
  public static String physicalAddress = "read MAC error!";
  public ReadMAC() {
  }
  public static String checkPhysicalAddress(){
  try{
  String line;
  Process process = Runtime.getRuntime().exec("cmd /c ipconfig /all");
  BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
  while ( (line=bufferedReader.readLine()) != null){
  if(line.indexOf("Physical Address. . . . . . . . . :") != -1){
  if(line.indexOf(":") != -1){
  physicalAddress = line.substring(line.indexOf(":")+2);
  break; //找到MAC,推出迴圈
  }
  }
  }
  process.waitFor();
  }catch(Exception e){
  e.printStackTrace();
  }
  return physicalAddress;
  }
  public static void main(String[] args) {
  System.out.println("原生MAC地址是: "+ ReadMAC.checkPhysicalAddress());
  }
  }

  編譯運行該程式的輸出結果2所示。


圖2

  由於每一台電腦的MAC地址都不同,所以該程式在不同電腦上運行結果都會不一樣。

  5 結束語

  作為一個跨平台語言,編寫的JAVA程式一般都與硬體無關,因而能運行在不同的作業系統環境。但這給編寫底層相關的程式時帶來不便。

  Java的應用程式都存在著一個與其運行環境相聯絡的Runtime對象,利用該對象可執行外部命令,在WindowsXP/NT/2000環 境中的命令IPCONFIG的輸出包含有MAC地址。本文編寫的Java程式,執行外部命令IPCONFIG,並通過分析該命令的輸入資料流而獲得原生 MAC地址。由於IPCONFIG命令是作業系統命令,所以該方法既方便又可靠。

  以上討論的程式適合於Windows XP/NT/2000作業系統,因為它是基於該作業系統的命令IPCONFIG格式的。由於不同作業系統讀取MAC地址的命令、以及命令輸出格式的不同, 所以該程式不能直接運用到其它系統。要移植到其它系統只需針對命令的輸出格式稍作修改。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.