今週も前回に引きつづきjava.netパッケージに関する機能拡張を紹介していきます。
今週紹介するのはネットワークインタフェースに関する情報取得です。
Javaはもともとハードウェアへのアクセスをなるべくさせない方針で開発されてきました。たとえば、Javaから直接メモリやI/Oにアクセスすることは限定されています。しかし、だんだんとその制限も緩んでいるようです。
Java SE 6ではネットワークインタフェースに関する制限が緩くなりました。具体的には、java.net.NetworkInterfaceクラスで情報取得のための新しいメソッドが多数定義されています。
NetworkInterfaceクラスはJ2SE 1.4で導入されたので、比較的新しいクラスです。このクラスは、たとえばUNIXであればle0とかeth0などで表されるネットワークインタフェースを表しています。
J2SE 1.4では、インタフェースのアドレスや名前などを取得することができました。Java SE 6ではこれに加えて、表1に示す情報を取得することができます。
名称 | メソッド名 | 戻り値の型 | 補足 |
---|---|---|---|
アドレス | getInterfaceAddresses | List <InterfaceAddress> |
アドレス、ブロードキャストアドレスなど |
サブインタフェース | getSubInterface | Enumeration <NetworkInterface> |
|
親インタフェース | getParent | NetworkInterface | このインタフェースがサブインタフェースの場合 |
起動状態 | isUp | boolean | 起動中であればtrue |
ループバック | isLookback | boolean | ループバックインタフェースであればtrue |
ポイントツーポイント | isPointToPoint | boolean | モデムでPPP接続などをしている場合はtrue |
マルチキャストの可否 | supportsMulticast | boolean | マルチキャストサポートしているかどうか |
ハードウェアアドレス | getHardwareAddress | byte[] | 通常はMACアドレスを示す |
最大転送単位(MTU) | getMTU | int | |
仮想インタフェース | isVirtual | boolean | 仮想インタフェースであればtrue |
getInterfaceAddressesメソッドの戻り値は、新しく導入されたInterfaceAddressクラスが使われています。InterfaceAddressクラスにはアドレスだけでなく、ブロードキャストアドレスおよび接頭辞長も一緒に保持するクラスです。
それでは、サンプルを使ってこれらのメソッドを使ってみましょう。
サンプルのソース NetworkInterfaceSample.java
このサンプルはNetworkInterface#getNetworkInterfacesメソッドを使用して、すべてのNetworkInterfaceオブジェクトを取得しています。そして、各NetworkInterfaceオブジェクトに対して表1のメソッドをコールしているだけです。
以下に情報を取得して、表示するメソッドを示します。
private void showInterfaceDetail(NetworkInterface netInterface) throws SocketException { // 名前 System.out.println("Name: " + netInterface.getName()); // 表示名 System.out.println("Display Name: " + netInterface.getDisplayName()); // アドレス List<InterfaceAddress> addresses = netInterface.getInterfaceAddresses(); for (InterfaceAddress address: addresses) { System.out.println("Address: "); // アドレス System.out.println(" Address: " + address.getAddress()); // ブロードキャストアドレス System.out.println(" Broadcast: " + address.getBroadcast()); // ネットワーク接頭辞長 System.out.println(" Prefix Length: " + address.getNetworkPrefixLength()); } // サブインタフェース Enumeration<NetworkInterface> subInterfaces = netInterface.getSubInterfaces(); while(subInterfaces.hasMoreElements()) { System.out.println("Sub Interface: " + subInterfaces.nextElement().getDisplayName()); } // サブインタフェースだった場合の親インタフェース NetworkInterface parent = netInterface.getParent(); if (parent != null) { System.out.println("Parent Interface: " + parent.getDisplayName()); } // 接続状態 System.out.println("起動中: " + (netInterface.isUp()? "YES": "NO")); // ループバック System.out.println("ループバック: " + (netInterface.isLoopback()? "YES": "NO")); // Point to Point System.out.println("PPP: " + (netInterface.isPointToPoint()? "YES": "NO")); // マルチキャストのサポート System.out.println("マルチキャスト: " + (netInterface.supportsMulticast()? "可": "不可")); // 物理アドレス byte hwAddress[] = netInterface.getHardwareAddress(); if (hwAddress != null) { System.out.print("MAC アドレス: "); for (byte segment: hwAddress) { System.out.printf("%02x ", segment); } System.out.println(); } // MTU System.out.println("MTU: " + netInterface.getMTU()); // 仮想インタフェース System.out.println("仮想インタフェース: " + (netInterface.isVirtual()? "YES": "NO")); System.out.println(); }
さて、これを実行してみましょう。ここではWindows XPを使用し、ネットワークインタフェースは有線を使用しているPCで実行してみました。
C:\>java NetworkInterfaceSample Name: lo Display Name: MS TCP Loopback interface Address: Address: /127.0.0.1 Broadcast: /127.255.255.255 Prefix Length: 8 起動中: YES ループバック: YES PPP: NO マルチキャスト: 可 MTU: 1520 仮想インタフェース: NO Name: eth0 Display Name: Intel(R) PRO/100 VE Network Connection - ?p?P?b?g ?X?P?W Address: Address: /192.168.XXX.XXX Broadcast: /192.168.XXX.255 Prefix Length: 21 起動中: YES ループバック: NO PPP: NO マルチキャスト: 可 MAC アドレス: XX XX XX XX XX XX MTU: 1500 仮想インタフェース: NO
実行した結果、ループバックとイーサネットのインタフェースが取得できました。なお、IPアドレスとMACアドレスは伏せ字にさせていただきました。
eth0はDisplay Nameが文字化けを起こしています。これはShift_JISでパケット スケと書かれています。Javaはこの文字をISO-8859-1として扱ってしまったため、文字化けしてしまったようです。
これに対し、Windows Vistaではアルファベット表示に変更されているので、文字化けは発生しません。
このように各ネットワークインタフェースの情報を取得できるようになりました。これらの情報を使用することはほとんどないかもしれません。とはいうものの、取得できるのとできないのでは大違いなのです。
著者紹介 櫻庭祐一 横河電機 ネットワーク開発センタ所属。Java in the Box 主筆 今月の櫻庭ここ数年、夏になると沖縄にいっています。去年までは雨に降られたことがなかったのですが、今年はとうとう台風に遭遇してしまいました。 沖縄のJavaコミュニティであるJava Kücheの一周年記念講演会で講演するため、先月の12日に沖縄に向かいました。ところが、同じく沖縄に来ていたのが台風4号。せっかくの、講演会も中止の憂き目にあってしまいました。 それでも、懇親会だけは開かれました。居酒屋にプロジェクターを持ち込み、講演の内容についてざっくばらんにお話しすることができました。 それにしても、沖縄の台風はすごいとは聞いていましたが、本当にすごかったです。 泊まっていたホテルは建物全体が風で揺れ、窓のサッシからも雨がしみこんできます。倒れているヤシの木も多数。 沖縄でも、今回のような大型台風の直撃は久しぶりだそうです。 なお、中止になってしまった講演会ですが、 8/8に再び講演会が企画されています。残念ながら櫻庭は参加できませんが、ひがやすをさんと羽生章洋さんが講演されます。ご興味をお持ちの方はぜひ参加してみてはいかがでしょうか。 |