JavaのInetAddressクラス

javaではIPアドレスを、java.net.InetAddressクラスで管理します。そこでよく使われるいくつかのメソッドを以下で紹介します。
このクラスには、コンストラクタが存在せず、次のstaticメソッドでInetAddressインスタンスを取得します。
逆に以上で得られたInetAddressのインスタンスより、次の情報が得られます。 実際の動作を次のプログラムで確認・検討ください。
01
02
03
04
05
06
07
08
09
10 11
12
13
14
15
16
17
18
19
20 21
22
23
24
25
26
27
28
29
import java.net.*;//InetAddress
public class PrintNetInfo {
	public static void main(String[] args) throws Exception {
		//ローカルのInetAddress(IPアドレス)を取得
		InetAddress inet  = InetAddress.getLocalHost();

		System.out.println("IPアドレス:" + inet.getHostAddress());
		String hostName = inet.getHostName();
		System.out.println("ホスト名:" + hostName);
		
		//IPアドレスのバイト列取得
		byte []ip = inet.getAddress();
		for(int i =0; i < ip.length; i++){
			System.out.printf("%02X  ", (0x0ff & ip[i]));
		}
		System.out.println("以上がIPアドレスの16進表示\n");
		
		//ホスト名から全てのIPアドレスを表示
		InetAddress []adrs = InetAddress.getAllByName(hostName);
		for(int i = 0; i < adrs.length; i++){
			System.out.println(adrs[i].getHostAddress());
		}
		
		//指定のIPアドレスからInetAddressを取得して表示
		inet = InetAddress.getByAddress(new byte[]{74,125,91,104});
		//inet = InetAddress.getByName("74.125.91.104");//これも可能
		System.out.println("ホスト名:" + inet.getHostName());
	}
}

以下に上記の実行例を示します。 19行でgetAllByNameを使っていますが、ネットワークカードが複数ある場合はその数だけIPアドレス情報が、複数出力されます。 以下無線と有線あるノートで、2つのアドレスを使っているマシンの例です。 当然に実行しているマシンの情報を取得する部分は、 そのマシンのデータ表示になります。 またセキュリティなど実行環境によって、 部分的実行できない場合があります。

Z:\net>java PrintNetInfo
IPアドレス:192.168.0.3
ホスト名:vista
C0  A8  00  03  以上がIPアドレスの16進表示

192.168.0.3
192.168.0.33
ホスト名:qy-in-f104.google.com
Z:\net>

NetworkInterfaceクラスを使った取得

上記のプログラムはシステムによって、InetAddress.getLocalHost()の戻り値が、ループバックアドレスの127.0.0.1となって、設定されたIPアドレスが得られないことがあります。
これは InetAddress.getLocalHost() がローカルマシンのホスツファイル情報を参照しているためで、システムによって、ここからIPアドレスが得られない場合があるのです。
hosts(ホスツ)とは、TCP/IP利用のコンピュータにおいて、IPアドレスとホスト名の対応を記述したテキストファイルです。Linuxの場合 /etc/hosts、Windows の場合は、 c:\Windows\system32\drivers\etcの位置にあります。
アドレスが得られない場合は、NetworkInterfaceクラスを使います。
これはネットワークインターフェイスカード(NIC)の情報を管理するクラスで、「lo」や「eth0」のような識別名で管理されます。
このクラスから InterfaceAddressを得て、そこからInetAddressを得る方法を使えば、そのインターフェイスが使っているIPアドレスが得られるでしょう。
これを使って、すべてのNetworkInterfacの名前を列挙し、次に"wlan0"の名前のインターフェイスから、IPアドレスを取得して表示しているコード例を示します。

package net;
import java.net.*;
import java.util.*;
public class NetInfo {//ネットワークインターフェイスカードのインターフェイス情報取得
	// すべてのネットワークインターフェイスの名前を列挙表示
	static void printAllNetworkInterface() throws Exception {
		Enumeration <NetworkInterface> netSet;//集合内の列挙操作に使う古い型
		netSet = NetworkInterface.getNetworkInterfaces();
		while(netSet.hasMoreElements()){//すべてのインターフェイスを走査
			NetworkInterface nInterface = (NetworkInterface) netSet.nextElement();
			System.out.print("  " + nInterface .getName() );//ネットワーク識別名
		}
	}
	// 引数のインターフェイスのIPアドレスをすべて表示
	static void printInterfaceAddress(String interfaceName) throws Exception {
		NetworkInterface wlan = NetworkInterface.getByName(interfaceName);
		List<InterfaceAddress>list = wlan.getInterfaceAddresses();
		for (InterfaceAddress interfaceAdr : list){//インターフェイス内のアドレス走査
			InetAddress inet2 = interfaceAdr.getAddress();
			IP.print(inet2);
		}
	}
	// 取得できるすべてのIPアドレスをすべて表示
	public static void printAllIP() throws Exception {
		Enumeration <NetworkInterface> netSet;//集合内の列挙操作に使う古い型
		netSet = NetworkInterface.getNetworkInterfaces();
		while(netSet.hasMoreElements()){//すべてのインターフェイスを走査
			NetworkInterface nInterface = (NetworkInterface) netSet.nextElement();
			List<InterfaceAddress>list = nInterface.getInterfaceAddresses();
			if( list.size() == 0 ) continue;
			System.out.println(nInterface .getName() );//ネットワーク識別名
			for (InterfaceAddress interfaceAdr : list){
				InetAddress inet = interfaceAdr.getAddress();
				IP.print(inet);//IPアドレスの表示
			}
		}
	}
	public static void main(String[] args) throws Exception {
		printAllNetworkInterface();//すべてのネットワークインターフェイスの名前を列挙
		System.out.println("\n以上--------次に「wlan0」インターフェイスが持つIPを列挙");
		printInterfaceAddress("wlan0");
		System.out.println("\n取得できるすべてのIPアドレスをすべて表示");
		printAllIP();
		InetAddress inet = NetInfo.getInetAddress4();
		System.out.println(inet.getHostAddress());
	}
 	// 最初に取得できたループバック以外のPv4のアドレスを返す。
	public static InetAddress getInetAddress4() throws Exception {
		InetAddress rtnInet = null;
		Enumeration <NetworkInterface> netSet;//集合内の列挙操作用
		netSet = NetworkInterface.getNetworkInterfaces();
		while(netSet.hasMoreElements()){//すべてのインターフェイスを走査
			NetworkInterface nInterface = (NetworkInterface) netSet.nextElement();
			List<InterfaceAddress>list = nInterface.getInterfaceAddresses();
			if( list.size() == 0 ) continue;
			for (InterfaceAddress interfaceAdr : list){
				InetAddress inet = interfaceAdr.getAddress();
				if(inet.isLoopbackAddress() ) continue;
				if(inet.getClass() == Inet4Address.class) {
					rtnInet = inet;
				}
			}
		}
		return rtnInet;
	}
}

実行例を示します。

  lo  net0  net1  net2  ppp0  eth0  eth1  eth2  ppp1  net3  wlan0  eth3  wlan1  net4  net5  net6  eth4  eth5  wlan2  wlan3  eth6  eth7  eth8  wlan4  wlan5  wlan6  wlan7  wlan8
以上--------次に「wlan0」インターフェイスが持つIPを列挙
        IPアドレス:192.168.11.108 ホスト名:TL40-41.scc01
        取得できたクラス名:java.net.Inet4Address
        IPアドレス:fe80:0:0:0:9d3b:28d:b4f8:498f%11 ホスト名:TL40-41.scc01
        取得できたクラス名:java.net.Inet6Address

取得できるすべてのIPアドレスをすべて表示
lo
        IPアドレス:127.0.0.1 ホスト名:127.0.0.1
        取得できたクラス名:java.net.Inet4Address
        IPアドレス:0:0:0:0:0:0:0:1 ホスト名:0:0:0:0:0:0:0:1
        取得できたクラス名:java.net.Inet6Address
wlan0
        IPアドレス:192.168.11.108 ホスト名:TL40-41.scc01
        取得できたクラス名:java.net.Inet4Address
        IPアドレス:fe80:0:0:0:9d3b:28d:b4f8:498f%11 ホスト名:TL40-41.scc01
        取得できたクラス名:java.net.Inet6Address
eth3
        IPアドレス:fe80:0:0:0:dda7:d3b:7950:5176%12 ホスト名:fe80:0:0:0:dda7:d3b:7950:5176%12
        取得できたクラス名:java.net.Inet6Address
wlan1
        IPアドレス:fe80:0:0:0:2cf1:69fb:e47f:6a7c%13 ホスト名:fe80:0:0:0:2cf1:69fb:e47f:6a7c%13
        取得できたクラス名:java.net.Inet6Address
net6
        IPアドレス:fe80:0:0:0:0:5efe:c0a8:b6c%16 ホスト名:fe80:0:0:0:0:5efe:c0a8:b6c%16
        取得できたクラス名:java.net.Inet6Address
192.168.11.108